Могу написать следующее:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}
f :: Integral a => (forall b. Num b => b) -> a
f = id
И все хорошо. Предположительно GHC может получить Integral
из Num
, так что все в порядке.
Я могу быть немного хитрее, но я все еще в порядке:
class Integral x => MyIntegral x
instance Integral x => MyIntegral x
class Num x => MyNum x
instance Num x => MyNum x
f' :: MyIntegral a => (forall b. MyNum b => b) -> a
f' = id
Итак, скажем, я хочу обобщить это, например:
g :: c2 a => (forall b. c1 b => b) -> a
g = id
Теперь очевидно, что это плюнет на пустышку, потому что GHC не может вывести c2
из c1
, так как c2
не ограничено.
Что мне нужно добавить к сигнатуре типа g
, чтобы сказать, что «вы можете получить c2
из c1
»?
Integral t
подразумеваетNum t
, а не наоборот. GHC должен извлечьNum
словарь из переданногоIntegral
словаря. И аналогично для других случаев, которые вы упомянули ниже. - person chi   schedule 07.05.2017