0

when implementing my own tool modules and funtions, I want to make sure that my function fails on specific input, such as assertFail (head []), but this assertFail function seems impossible to be implemented in Haskell, is there any way to hack it?

luochen1990
  • 3,689
  • 1
  • 22
  • 37
  • 3
    What do you mean when you say "fail"? A runtime exception? A return value representing an error? A `MonadThrow` call? – sara Mar 27 '19 at 13:23
  • If you just want a quick and dirty escape hatch for debugging your own code, then `error "my error message"` matches any type so can go anywhere. Otherwise @sara is completely right that there are approaches to handle matters more gracefully (like other languages might use try .. catch) if that's what you're looking for ? – moonGoose Mar 27 '19 at 13:41

2 Answers2

3

If I understand what you want correctly, you can use spoon:

import Control.Spoon

assertFail x = case spoon x of
    Nothing -> ()
    Just _ -> error "unexpected success"

A relevant question: Is spoon unsafe in Haskell?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 1
    A much more extensive package specifically for property testing: [`ChasingBottoms`](http://hackage.haskell.org/package/ChasingBottoms). – dfeuer Mar 27 '19 at 16:55
0

One way to prototype assertFail could be assertFail = undefined, because evaluating it would raise a runtime exception. Another would be using error.

If you're building a test framework, a proper design would likely involve total functions (that never raise a runtime error) which return something like Maybe String for a possible error message.

If what you need is indeed assertRaises, take a look at Control.Exception which likely would help.

9000
  • 39,899
  • 9
  • 66
  • 104
  • 2
    This would be an unconditional failure, akin to Python's `fail` method in the `unittest` module. The user wants something more like `assertRaises(SomeException, some_func, ...)`, which asserts that a particular call will fail. – chepner Mar 27 '19 at 13:51
  • Sorry, it's due to wrong naming. In all frameworks I've seen `assertFail` fails unconditionally; `assertRaises` is indeed a very different beast. I've extended my answer a bit. – 9000 Mar 27 '19 at 13:54