什么"!!" 在哈斯克尔意味着什么?

use*_*558 12 haskell

Haskell wiki网站上有两个函数:

功能1

fib = (map fib' [0 ..] !!)
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)
Run Code Online (Sandbox Code Playgroud)

功能2

fib x = map fib' [0 ..] !! x
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)
Run Code Online (Sandbox Code Playgroud)

什么是"!!" 意思?

Joh*_*ler 23

这实际上更难以阅读,然后它首先看起来像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.
Run Code Online (Sandbox Code Playgroud)

让我们假设您需要帮助阅读此内容.第一行告诉我们这(!!)是一个函数,它接受一个事物列表([a]),Int然后返回列表中的一个东西(a).描述会告诉您它的作用.它将为您提供由索引编制的列表元素Int.所以,xs !! i就像xs[i]在Java,C或Ruby中一样.

现在我们需要谈谈运营商如何在haskell中工作.我不打算在这里给你完整的东西,但我至少会告诉你,在这里还有更多东西,然后你将在其他编程语言中遇到什么.运算符"总是"接受两个参数并返回一些东西(a -> b -> c).你可以像普通函数一样使用它们:

add x y
(+) x y -- same as above
Run Code Online (Sandbox Code Playgroud)

但是,默认情况下,您也可以在表达式之间使用它们(这个词是'中缀').您还可以使正常函数像具有backtics的运算符一样工作:

x + y
x `add` y -- same as above
Run Code Online (Sandbox Code Playgroud)

您给出的第一个代码示例(特别是对于新的haskell编码器)的作用是将!!运算符用作函数而不是典型的运算符(中缀)位置.让我添加一些绑定,以便更清楚:

-- 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)
Run Code Online (Sandbox Code Playgroud)

您现在可以回到示例1.确保您了解其map fib' [0 ..]含义.

我很抱歉你的问题被投票了,因为如果你理解了答案的内容很容易查找,但如果你不知道运营商是否存在于haskell,那么很难在精神上解析上面的代码.


小智 6

(!!):: [a] - > Int - > a

列表索引(下标)运算符,从0开始.它是更通用的genericIndex的一个实例,它接受任何整数类型的索引.

见这里:http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#g:16