是否有可能在Idris中进行模式匹配?

时间:2018-06-03 15:47:00

标签: 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)。

除了理解是否有办法解决这个问题外,我还要了解伊德里斯为何会以这种方式行事。

1 个答案:

答案 0 :(得分:1)

好吧,如果我理解正确,这可能有效

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