Haskell wiki网站上写了两个函数:
功能1
fib = (map fib' [0 ..] !!)
where
fib' 0 = 0
fib' 1 = 1
fib' n = fib (n - 1) + fib (n - 2)
功能2
fib x = map fib' [0 ..] !! x
where
fib' 0 = 0
fib' 1 = 1
fib' n = fib (n - 1) + fib (n - 2)
“!!”是什么意思?
答案 0 :(得分:22)
这实际上更难以阅读,因为它最初似乎是因为haskell中的运算符比其他语言更通用。
我们所有想要告诉你的第一件事就是自己去看看。如果您还不知道hoogle,那么现在是时候熟悉它了。你可以要求它告诉你一个函数通过名称做什么或(这更酷)你可以给它一个函数的类型,它可以提供关于哪个函数实现该类型的建议。
这是hoogle告诉你的关于这个功能(操作员)的内容:
(!!) :: [a] -> Int -> a
List index (subscript) operator, starting from 0. It is an
instance of the more general genericIndex, which takes an index
of any integral type.
让我们假设您需要帮助阅读此内容。第一行告诉我们(!!)
是一个函数,它接受事物列表([a]
)和Int
然后返回列表中的一个事物({{1} })。描述会告诉您它的作用。它将为您提供由a
索引的列表元素。因此,Int
与Java,C或Ruby中的xs !! i
类似。
现在我们需要谈谈运营商在haskell中的运作方式。我不打算在这里给你完整的东西,但我至少会告诉你,在这里还有更多东西,然后你将在其他编程语言中遇到什么。运算符“总是”接受两个参数并返回一些东西(xs[i]
)。你可以像普通函数一样使用它们:
a -> b -> c
但是,默认情况下,您也可以在表达式之间使用它们(这个词是'中缀')。您还可以使正常函数像具有反复逻辑的运算符一样工作:
add x y
(+) x y -- same as above
您给出的第一个代码示例(特别是对于新的haskell编码器)的原因是x + y
x `add` y -- same as above
运算符用作函数而不是典型的运算符(中缀)位置。让我添加一些绑定,以便更清楚:
!!
您现在可以回到示例1.确保您了解-- return the ith Fibonacci number
fib :: Int -> Int -- (actually more general than this but do't worry about it)
fib i = fibs !! i
where
fibs :: [Int]
fibs = map fib' [0 ..]
fib' :: Int -> Int
fib' 0 = 0
fib' 1 = 1
fib' n = fib (n - 1) + fib (n - 2)
的含义。
我很抱歉你的问题被投了下来,因为如果你理解了答案的内容很容易查找,但如果你不知道运营商是否存在于haskell,那就很难了精神上解析上面的代码。
答案 1 :(得分:6)
(!!):: [a] - > Int - >一个
列表索引(下标)运算符,从0开始。它是更通用的genericIndex的一个实例,它接受任何整数类型的索引。
见这里:http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#g:16