How to compose `not` with a function of arbitrary arity?

前端 未结 4 1595
囚心锁ツ
囚心锁ツ 2020-11-29 01:21

When I have some function of type like

f :: (Ord a) => a -> a -> Bool
f a b = a > b

I should like make function which wrap this

4条回答
  •  我在风中等你
    2020-11-29 02:21

    Re: What am I doing wrong?:

    I think your combinator is fine, but when you let-bind it at the top level, one of Haskell's annoying 'default rules' comes into play and the binding isn't generalized:

    Prelude> :ty (n f)
    (n f) :: (Ord t) => t -> t -> Bool
    Prelude> let g = n f
    Prelude> :ty g
    g :: () -> () -> Bool
    

    I think you may be getting clobbered by the 'monomorphism restriction' as it applies to type classes. In any case, if you get out of the top-level loop and put things into a separate file with an explicit type signature, it all works fine:

    module X where
    
    n f = (\a -> \b -> not $ f a b)
    f a b = a > b
    
    g :: Ord a => a -> a -> Bool
    g = n f
    

    Bonus question: to do this with more and more type parameters, you can try playing scurvy tricks with the type-class system. Two papers to consult are Hughes and Claessen's paper on QuickCheck and Ralf Hinze's paper Generics for the Masses.

提交回复
热议问题