【问题标题】:Non exhaustive pattern in function in GHCiGHCi 中的非详尽功能模式
【发布时间】:2019-01-25 11:34:37
【问题描述】:

我想创建一个显示列表最后一个元素的函数。 这是我的代码:

ghci> let myLast :: [a] -> a
ghci> let myLast [] = error 
ghci> let myLast [x] = x
ghci> let myLast (x:xs) = myLast xs

我收到以下错误:

***Exception: Non-exhaustive patterns in function myLast

我知道您在遗漏案例时会收到此错误,但我想我已经包含了所有可能性。有什么想法吗?

【问题讨论】:

    标签: function haskell multiline read-eval-print-loop ghci


    【解决方案1】:

    如果您在每一行中使用let,则每个定义都会创建一个名为myLast 函数,从而覆盖所有先前的定义。所以你最终得到的相当于

    GHCi> 让 myLast (x:xs) = myLast xs

    一个人。

    您可能想要制作一个 haskell 文件,例如 MyLast.hs,其中包含

    module MyLast where
    
    myLast :: [a] -> a
    myLast [] = error 
    myLast [x] = x
    myLast (x:xs) = myLast xs
    

    然后您可以使用 ghci MyLast.hs 将该文件加载到 GHCi。

    关键字let 仅在您已经在GHCi 中(或者,在像IO 这样的monad 中,或在另一个函数中)并且想要进行本地定义 时才需要。但是你必须只使用一次let,例如

    GHCi> let myLast :: [a]->a; myLast [] = 错误;我的最后 [x] = x; myLast (x:xs) = myLast xs

    twiceLast :: [Int] -> [Int]
    twiceLast = let myLast [] = error 
                    myLast [x] = x
                    myLast (x:xs) = myLast xs
                in \xs -> 2 * last xs
    

    不过,我更愿意写成

    twiceLast = (2*) . myLast
     where myLast [] = error 
           myLast [x] = x
           myLast (x:xs) = myLast xs
    

    【讨论】:

      【解决方案2】:

      在 ghci 中,let 的每次使用都会引入一个新定义,因此您需要多次重新定义函数,而不是添加案例。

      两种选择:

      • 将定义放在一个文件中并使用:r 命令加载它
      • 使用:{ ... :}输入多行:

      例如:

      *Main> :{
      *Main| let foo [] = True
      *Main|     foo _ = False
      *Main| :}
      *Main>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 2018-09-06
        • 2021-11-30
        相关资源
        最近更新 更多