8

考虑这个实现on

on f g = curry $ (. bimap g g) $ uncurry f

它是什么类型的?GHC 会说(b -> b -> c) -> (a -> b) -> a -> a -> c,这是一个很好的猜测。但它错过了实例on (+) toInteger。让我们尝试解决这个问题(使用、RankNTypesKindSignatures):AllowAmbiguousTypesConstraintKinds

on :: forall (co :: * -> Constraint) a1 a2 b c . 
      (co a1, co a2) => 
      (b -> b -> c) 
   -> (forall a . co a => a -> b)
   -> a1 -> a2 -> c

然后进行类型检查。但是当我们尝试

> :t (+) `on` toInteger

我们得到

• Couldn't match type ‘c’ with ‘Integer’
    ‘c’ is untouchable
      inside the constraints: co a
      bound by a type expected by the context:
                 forall a. co a => a -> c
      at <interactive>:1:1-18
  ‘c’ is a rigid type variable bound by
    the inferred type of it :: (co a1, co a2, Num c) => a1 -> a2 -> c
    at <interactive>:1:1
  Possible fix: add a type signature for ‘it’
  Expected type: a -> c
    Actual type: a -> Integer
• In the second argument of ‘on’, namely ‘toInteger’
  In the expression: (+) `on` toInteger

那是什么意思?

4

0 回答 0