解决Project Euler上的问题后,我在论坛中遇到了以下Haskell代码:
fillRow115 minLength = cache where
cache = ((map fillRow115' [0 ..]) !!)
fillRow115' 0 = 1
fillRow115' cells = sum (map cache [0..cells-minLength]) + cache (cells-1)
Run Code Online (Sandbox Code Playgroud)
我本周刚开始学习Haskell,似乎无法理解这段代码.有人可以解释以下2项:
minLength,但该函数需要2个参数才能在ghci中运行.这另一个论点在哪里发挥作用?!! 是列表索引运算符,并在调用时返回第n个元素[list] !! n.上面的代码似乎只用一个参数来调用它.那是做什么的?PS如果有人想要复制此代码来解决Project Euler问题,它似乎没有给出正确的答案.
这另一个论点在哪里发挥作用?
让我们进一步简化这个问题.你可能知道这个head功能:
head [] = error "something bad"
head (x:_) = x
Run Code Online (Sandbox Code Playgroud)
你可能很傻并定义你自己的头部函数,只需调用head:
myHead xs = head xs
Run Code Online (Sandbox Code Playgroud)
并注意左侧和右侧都应用变量xs,因此我们可以执行所谓的eta-reduction并导致:
myHead = head
Run Code Online (Sandbox Code Playgroud)
类型签名可能会使点回家:
myHead :: [a] -> a
myHead = (head :: [a] -> a)
Run Code Online (Sandbox Code Playgroud)
所以在你的情况下,fillRow115需要第二个参数,因为它等于cache,这需要一个参数 - 这就把我们带到了你的第二个问题.
上面的代码似乎只用一个参数来调用它.那是做什么的?
考虑这个功能+.如果你想创建一个总是加2的函数,你可以"部分应用"2到函数+:
addTwo = (+2) -- (2+) would work just as well
Run Code Online (Sandbox Code Playgroud)
所以你正在查看列表索引功能!!:
(!!) :: [a] -> Int -> a
Run Code Online (Sandbox Code Playgroud)
并且对自己说,这只适用于某些列表.应用我们对部分应用程序的了解,我们得到了一种类型:
(someList !!) :: Int -> a
Run Code Online (Sandbox Code Playgroud)
所以这实际上是从Ints到列表元素的函数.
如果这还没有点击,只需替换someList你正在使用的列表:
someList = map fillRow115' [0..]
(someList !!) === ((map fillRow 115' [0..]) !!)
Run Code Online (Sandbox Code Playgroud)