xs = [1,2,3]::[Float]
ys = map (+) xs
这是旧测试中的问题,没有解决方案表。
问题:
1)ys
有哪种签名?
2)解释原因并绘制ys
的样子
对于第一个问题,我知道xs
的类型为float
,因此应ys
(我也在ghci中运行程序)。
至于第二个我不知道,因为当我运行代码时没有任何反应。当我在一个单独的行上运行它并运行ys
时,我收到一个错误。
有人可以帮我提示吗?
答案 0 :(得分:3)
呃,不。对于第一个问题,我知道
xs
的类型为float
xs
类型为[Float]
:列表的浮动广告。
所以应
ys
ys
不与xs
具有相同的类型。您可能这么认为是因为您已经读过+
要求参数和结果具有相同的类型:
(+) :: Num a => a -> a -> a
...或者如果您将其实例化为Float
个数字
(+) :: Float -> Float -> Float
这是正确的,但(+)
不是endomorphism(将类型映射到自身的函数,因为如果ys
与{{1}的类型相同,则必须如此因为它有两个数字参数。
使用xs
,您将map (+)
视为单个参数的函数,而不是两个参数。在大多数编程语言中,这实际上是一个错误,但在Haskell中却不是这样:在Haskell中,所有函数实际上只有一个参数。具有“多个参数”的函数实际上只是functions on interesting types, that make it seem as if you're passing multiple arguments。特别是(+)
的签名实际上是:
(+)
因此,被视为单参数函数,(+) :: Float -> (Float -> Float)
实际上将数字映射到数字 - 内同态。因此,
(+)
和
map (+) :: [Float] -> [Float -> Float]
- 数字函数列表。具体来说,就是这个清单:
ys :: [Float -> Float]
例如,我可以像这样使用它:
ys = [(+) 1 , (+) 2 , (+) 3 ]
≡ [(1+) , (2+) , (3+) ]
≡ [\n -> 1+n, \n -> 2+n, \n -> 3+n]
顺便说一下,IMO你问的问题是错误的。在Haskell中,你不想考虑一些代码并想知道它有什么类型 - 这更像是ML甚至是Lisp方法。我总是从类型签名开始,然后计算出“从外到内”的实现(typed holes非常方便)。与过程语言相比,这种可能性是函数式编程的一大优势。
答案 1 :(得分:2)
我现在没有ghci,如果我说的话是错的,我道歉。
xs
类型为[Float]
,ys
类型为[Float -> Float]
(它是一个函数列表,每个函数都会Float
并返回{{1} }})。 Float
将为ys
,因为[(+) 1, (+) 2, (+) 3]
会将map
应用于(+)
中的每个元素。但是您无法打印xs
,因为函数不会派生ys
答案 2 :(得分:1)
ys type为Show
,接收数字的函数列表返回数字+1(前一个elem),数字+2(第二个)和数字+3(最后一个)。
请记住,[Float -> Float]
是一个应用了每个列表元素的单个参数,因此它确实返回另一个函数。
如果要添加列表中的所有项目,则应使用reduce函数,例如+
。
foldl
我希望这会有所帮助。
瓦尔