substitute':: (Eq a)=> a -> a -> [a] -> [a]
substitute' x y = map substituteOne
where
substituteOne x' | x == x' = y
| otherwise = x'
因此,此函数的要点是,它将接受类型a的两个输入和类型a的列表,并将列表[a]中的所有元素从“第一个” a替换为“第二个” a。至少任务描述就是这样。
我已经实现了递归版本,但是还需要带有where子句的函数。
那么这就是解决方案。不知何故我有问题:
如果需要,结果如下:
substitute' 5 10 [1, 5, 2, 5, 3, 5]
[1,10,2,10,3,10]
答案 0 :(得分:3)
(1)第二行中的
substituteOne
如何不带任何参数?
(2)我们在哪里提供列表作为输入?或者我们在哪里声明该列表的作用?我的意思是编译和执行它是可行的,但是以某种方式我看不到它
参数仍然存在;这是currying在起作用。考虑section of an infix operator (+1)
,这是partial application的特例。给定一个数字,它将产生一个更大的数字。证人:
λ> :t (+1)
(+1) :: Num a => a -> a
我们可以定义一个函数,通过命名列表来增加列表的所有元素
λ> :t \l -> map (+1) l
\l -> map (+1) l :: Num b => [b] -> [b]
但是由于currying而变得不必要。
λ> :t map (+1)
map (+1) :: Num b => [b] -> [b]
毕竟,这是功能性编程。使用Haskell,我们可以像其他语言操纵字符串一样轻松地操纵函数。
(3)是
x'
?它从未在任何地方定义,我们只是以某种方式开始使用它(也许也提到问题1)
但是您要做将x'
定义为substituteOne
的参数!
考虑map
的类型:
λ> :t map
map :: (a -> b) -> [a] -> [b]
它的第一个参数是一个参数的函数。为了使您的程序能够进行类型检查,类型必须要对齐。我们可以通过添加可选的类型注释来为substituteOne
强调这一点-但必须更加努力(通过启用scoped type variables扩展),因为substituteOne
是一个内部函数,引用了外部函数范围
substitute':: forall a. Eq a => a -> a -> [a] -> [a]
substitute' x y = map substituteOne
where
substituteOne :: a -> a
substituteOne x' | x == x' = y
| otherwise = x'
(4)
map
需要一个函数和一个列表,这样它才能起作用。这里我们有map
函数_
。是指2。但是substituteOne x'
的输出是什么?
在应用程序点使用未命名的参数,就像您的代码对map substituteOne
所做的那样,被称为pointfree style。在您的情况下,有两个不可见的“点”或变量名:substituteOne
的参数和map
的列表参数。
您可能对所有事情都一目了然,如
substitute'' :: Eq a => a -> a -> [a] -> [a]
substitute'' x y l = map (\x' -> if x == x' then y else x') l
但是相比之下,这更混乱了。
由substituteOne
产生的列表中收集了map
产生的值。
答案 1 :(得分:1)
substitute
的类型为a -> a -> [a] -> [a]
,这意味着它接受一个一个参数并返回一个类型为a -> [a] -> [a]
的函数。这是因为(->)
是右关联的,并且上面的类型等效于a -> (a -> [a] -> [a])
。
由于函数应用程序是左关联的,因此像substitute x y
这样的调用等效于(substitute x) y
; y
是substitute x
返回的函数的参数。
当一个人写
substitute x y = ...
是
的语法糖substitute = \x -> \y -> ...
此外,由于map substituteOne'
的类型为[a] -> [a]
,因此它是substitute x y
返回的合适值。
答案 2 :(得分:0)
substitute1
采用参数x'
。 |
和=
字符之间的位是保护条件。由于此特定功能只有一个条件,因此您可以像这样重写它:
substitute1 x' = if x == x' then y else x'
因为它位于where
子句中,substitute1
也可以访问主函数的参数x
和y
。