在haskell循环异常中,在其函数体中没有循环

时间:2015-01-20 10:48:52

标签: haskell ghci

我是Haskell的新手,并编写了以下小代码,但它失败了循环异常。问题是代码不使用循环,甚至递归。 这让我疯了!

gameList :: [Int]->Int->Int->[(Int, Int)]
gameList  org pos step =
    let next  = (mod (pos + step)  2) ;
        pos = next;             
    in  [(pos, pos)]

然后将其保存在一个文件中,并成功将其加载到具有交互模式的GHC中。 像这样调用它            gameList [1,2,3] 0 1

它会抛出错误“[(***异常:<>”

GHCI信息:WinGHCi 1.0.6 救救我!

2 个答案:

答案 0 :(得分:4)

  

“不使用循环,甚至递归”

我担心它确实会使用递归,虽然这种方式在非懒惰的语言中甚至是不可能的!

关键是你的参数pos从未在任何地方实际使用,它会立即被pos块中定义的let所遮蔽(GHC会警告你,{ {1}}!)。所以你的代码相当于

-Wall

其中gameList org _ step = let next = (mod (pos + step) 2) ; pos = next; in [(pos, pos)] 是根据next定义的posnext是......等等。

显而易见的解决方法是删除行pos = next,这完全没必要。

gameList org pos step
  = let next  = (pos + step) `mod` 2
    in  [(next, next)]

答案 1 :(得分:2)

  

不使用循环,甚至是递归

这不正确,这就是原因。

gameList :: [Int]->Int->Int->[(Int, Int)]
gameList  org pos step =              -- this is an unused argument named pos
  let next  = (mod (pos + step)  2) ; -- here we define next in terms of pos
        pos = next;                   -- ... which is defined here in terms of next
    in  [(pos, pos)]                  -- here we use this circularly-defined pos

请参阅,let不是作业,也不是"已执行"从上到下。 let引入了一组相互递归定义。所以这个

let next  = (mod (pos + step)  2) ;
    pos = next;             

根本不使用pos函数参数。