我是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 救救我!
答案 0 :(得分:4)
“不使用循环,甚至递归”
我担心它确实会使用递归,虽然这种方式在非懒惰的语言中甚至是不可能的!
关键是你的参数pos
从未在任何地方实际使用,它会立即被pos
块中定义的let
所遮蔽(GHC会警告你,{ {1}}!)。所以你的代码相当于
-Wall
其中gameList org _ step =
let next = (mod (pos + step) 2) ;
pos = next;
in [(pos, pos)]
是根据next
定义的pos
,next
是......等等。
显而易见的解决方法是删除行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
函数参数。