是否可以在 Idris 中使模式匹配惰性化?

Is it possible to make pattern matching lazy in Idris?

在 Haskell 中,我们可以执行以下操作而不会出现运行时错误 (ref):

mytake  0     _           =  []
mytake  _     []          =  []
mytake  n     (x:xs)      =  x : mytake (n-1) xs

print( mytake 0 (undefined::[Int]) )

在 Idris 中,我们可以做类似的定义,但行为不同:

mytake : Integer -> List a -> List a
mytake  0     _           =  []
mytake  _     []          =  []
mytake  n     (x::xs)      =  x :: mytake (n-1) xs

printLn( mytake {a = Nat} 0 ?undefined )

在这种情况下,我们得到 ABORT: Attempt to evaluate hole Main.undefined。我知道 Idris 不是一种懒惰的语言,但我的印象是模式匹配参数可能与数据结构评估逻辑分开(在 Idris 中可以回避,例如 Stream)。

除了了解是否有办法解决这个问题之外,我还很高兴知道 Idris 为什么会这样。

好吧,如果我没理解错的话,这可行

module Main

mytake : Integer -> Lazy (List a) -> List a
mytake  0     _          = []
mytake  _     []         = []
mytake  n     (x::xs)    = x :: mytake (n-1) xs


main : IO ()
main = printLn (mytake {a = Nat} 0 ?undefined)

但是编译时出现奇怪的错误

andrey@linux:~/idris> idris -o test test.idr
idris: src/Idris/Core/CaseTree.hs:(645,1)-(654,51): Non-exhaustive patterns in function varRule

回答你问题的第二部分: 这主要是因为急切的评估更容易预测。此问题在非官方常见问题解答中

https://github.com/idris-lang/Idris-dev/wiki/Unofficial-FAQ#why-isnt-idris-lazy