我有以下常用的代码来计算Haskell中的第n个Fibonacci数:
fibonacci :: Int -> Integer
fibonacci = (map fib [0..] !!)
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
Run Code Online (Sandbox Code Playgroud)
使用这个,我可以做如下调用:
ghci> fibonacci 1000
Run Code Online (Sandbox Code Playgroud)
并得到几乎即时的答案.
但是,如果我修改上面的代码,使它不是无点样式,即
fibonacci :: Int -> Integer
fibonacci x = (map fib [0..] !!) x
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
Run Code Online (Sandbox Code Playgroud)
它要慢得多.在某种程度上,如一个电话
ghci> fibonacci 1000
Run Code Online (Sandbox Code Playgroud)
挂起.
我的理解是上面两段代码是等价的,但GHCi要求不同.有没有人对这种行为有解释?
这感觉就像一个愚蠢的问题,但我无法在Java文档中的任何地方找到答案.如果我宣布两个整数然后除以它们,到底发生了什么?他们是转换为floats/doubles第一,分裂,然后转回一个integer,还是作为整数"完成"?
而且,纯粹来自实验,整数除法似乎将答案舍入为零(即3/2 = 1和-3/2 = -1).我是否正确地相信这一点?
如果我想找到列表的排列,我知道排列的数量由多项式系数给出.例如,"MISSISSIPPI"有11个字母,'S'出现4次,'I'出现4次,'P'出现两次,'M'出现一次.所以"MISSISSIPPI"的排列数等于11!/(4!4!2!)= 34650.
如果我加载GHCi并写:
ghci> import Data.List
ghci> permutations [1,2,3]
Run Code Online (Sandbox Code Playgroud)
它会回来
[[1,2,3],[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2]]
Run Code Online (Sandbox Code Playgroud)
正如所料.
但如果我写
ghci> permutations [1,0,0]
Run Code Online (Sandbox Code Playgroud)
它现在会回归
[[1,0,0],[0,1,0],[0,0,1],[0,0,1],[0,1,0],[1,0,0]]
Run Code Online (Sandbox Code Playgroud)
......这非常令人失望.由于有三个元素,其中两个出现两次,一个人希望只有6!/ 2!= 3个排列,即
[[1,0,0],[0,1,0],[0,0,1]]
Run Code Online (Sandbox Code Playgroud)
而不是通过将列表中的每个元素视为不同而生成的六个.
1)为什么Haskell以上述方式实现"排列"(即将列表的所有元素视为不同?)
2)是否有任何标准库函数可以计算"真实"排列意义下的列表排列?