首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell/HSpec:了解错误消息

Haskell/HSpec:了解错误消息
EN

Stack Overflow用户
提问于 2014-07-25 18:24:38
回答 2查看 246关注 0票数 2

我有下面的函数,它应该返回列表的倒数第二个元素:

代码语言:javascript
复制
myButLast :: [a] -> a
myButLast [] = error "List has less than one element!"
myButLast [x] = error "List has less than one element!"
myButLast [x,_] = x
myButLast (_:xs) = myButLast xs

当我将它加载到ghci中时,它适用于所有特殊情况,但当我尝试使用HSpec测试它时,我在运行此规范时出现错误:

代码语言:javascript
复制
main :: IO ()
main = hspec $ do

  describe "myButLast" $ do

    -- removed other specs --

    it "throws an error when called with a singleton list" $
      myButLast [1] `shouldThrow` anyErrorCall

以下是错误消息:

代码语言:javascript
复制
No instance for (Num (IO a0)) arising from the literal `1'
    Possible fix: add an instance declaration for (Num (IO a0))
    In the expression: 1
    In the first argument of `myButLast', namely `[1]'
    In the first argument of `shouldThrow', namely `myButLast [1]'

有趣的是,在测试myButLast []而不是myButLast [1]时,编译器不会报错,尽管两个表达式的结果定义完全相同。

EN

回答 2

Stack Overflow用户

发布于 2014-07-25 22:12:44

正如西蒙所指出的:

myButLast [1] 只是有一个错误的类型,即Num a => a,而shouldThrow需要一个IO a类型的第一个参数。

所以,更有趣的问题是:

编译器为什么不抱怨 myButLast []**?**的类型

这样做的原因是:由于文字[]也可以是[IO a]类型,编译器会推断myButLast []的类型为IO a,因为这是唯一有效的shouldThrow第一个参数。

票数 1
EN

Stack Overflow用户

发布于 2018-03-29 11:00:31

要回答问题背后的问题:要编写测试,您需要使用evaluate

代码语言:javascript
复制
import Control.Exception.Base

main :: IO ()
main = hspec $ do

  describe "myButLast" $ do

    it "throws an error when called with a singleton list" $
      evaluate (myButLast [1]) `shouldThrow` anyErrorCall
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24953562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档