
Hello fellow Haskellers! I'm approaching learning the basics of Haskell by going through https://wiki.haskell.org/99_questions. At the same time I write tests for my code in Hspec. Consider question no. 2: "Find the last but one element of a list". My solution: -- Problem 02 myButLast :: [a] -> a myButLast [] = error "Empty list" myButLast [x] = error "List has only one element" myButLast [x1,x2] = x1 myButLast (x:xs) = myButLast xs and a a test: describe "02 myButLast" $ do it "returns the last but one element of a list" $ do myButLast [] `shouldThrow` anyErrorCall myButLast [1] `shouldThrow` anyErrorCall -- <- this line causes the problem myButLast [1..4] `shouldBe` 3 myButLast ['x','y','z'] `shouldBe` 'y' myButLast "abc" `shouldBe` 'b' Building tests with stack test command causes the below compilation error: • No instance for (Num (IO a0)) arising from the literal ‘1’
• In the expression: 1 In the first argument of ‘myButLast’, namely ‘[1]’ In the first argument of ‘shouldThrow’, namely ‘myButLast [1]’ | 27 | myButLast [1] `shouldThrow` anyErrorCall |
From what I understand, type of myButLast [1] is different than expected by shouldThrow. What I don't understand is why exactly it behaves so and how to fix this problem. Only that one assertion doesn't compile. The others are fine. Particularly, why does myButLast [] `shouldThrow` anyErrorCall work but with one element it doesn't?
Can you please give me a hand?