Using Haskell's types to replace assert statements or if checks in other languages

后端 未结 3 1991
执笔经年
执笔经年 2021-02-19 15:07

Sorry if the question is very elementary, I am still very new to Haskell. Lets say I have a function that can only work with two numbers that are in the golden ration (1.618), h

3条回答
  •  借酒劲吻你
    2021-02-19 15:41

    The best you can do practically is a run-time check. There could be some type-level calculus I don't know (see luqui's comment), but that's not pratical in Haskell.

    You could use an assert, which is what you want to replace,

    checker :: a -> b -> Bool
    checker x y = x * 1.618 `approxEqual` y
    
    unsafeMyfun :: a -> b -> c
    unsafeMyfun x y = assert (checker x y) (doRealThingWith a b)
    

    or return a Maybe a (or Either err a) to avoid exceptions which cannot be caught in pure functions,

    myfun :: a -> b -> Maybe c
    myfun x y = do
                  guard $ checker x y
                  return $ doRealThingWith x y
    

    or use a custom contract type as in Tom's answer etc. In any way, it's not possible to check the constraint in compile time. In fact, due to the IO monad, any compile-time constraint cannot be precise.

提交回复
热议问题