mogę napisać następujący:ograniczające ograniczenia
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}
f :: Integral a => (forall b. Num b => b) -> a
f = id
I wszystko jest dobrze. Przypuszczalnie GHC może uzyskać Integral
z Num
, więc wszystko jest w porządku.
mogę być nieco tricker, ale nadal jestem w porządku:
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
Więc powiedzmy, że chcę uogólniać to tak:
g :: c2 a => (forall b. c1 b => b) -> a
g = id
Teraz oczywiście będzie pluć manekin, ponieważ GHC nie może wyprowadzić c2
z c1
, ponieważ c2
nie jest ograniczony.
Co muszę dodać do podpisu typu g
, aby powiedzieć, że "można uzyskać c2
z c1
"?
Kiedy mówisz "wyprowadzić X z Y", wolałbym powiedzieć "wyprowadzić Y z X". W twoim pierwszym przykładzie mamy to, że 'Integralna t' implikuje' Num t', a nie na odwrót. GHC musi wyodrębnić słownik 'Num' z podanego' Integralnego'. I podobnie w innych przypadkach wspomniałeś poniżej. – chi