Haskell代码解释

时间:2016-09-18 09:50:20

标签: haskell

xs = [1,2,3]::[Float]
ys = map (+) xs

这是旧测试中的问题,没有解决方案表。

问题:

1)ys有哪种签名?

2)解释原因并绘制ys的样子

对于第一个问题,我知道xs的类型为float,因此应ys(我也在ghci中运行程序)。 至于第二个我不知道,因为当我运行代码时没有任何反应。当我在一个单独的行上运行它并运行ys时,我收到一个错误。

有人可以帮我提示吗?

3 个答案:

答案 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

我希望这会有所帮助。

瓦尔