ho qualche tipo di artificioso:vincolo polimorfico
{-# LANGUAGE DeriveFunctor #-}
data T a = T a deriving (Functor)
... e quel tipo è l'istanza di una classe artificiosa:
class C t where
toInt :: t -> Int
instance C (T a) where
toInt _ = 0
Come posso esprimere in un vincolo di funzione che è T a
un'istanza di qualche classe per tutti a
?
Ad esempio, si consideri la seguente funzione:
f t = toInt $ fmap Left t
Intuitivamente, mi sarei aspettato la funzione di cui sopra a lavorare dal toInt
opere T a
per tutti a
, ma non posso esprimere che nel tipo. Questo non funziona:
f :: (Functor t, C (t a)) => t a -> Int
... perché quando applichiamo fmap
il tipo è diventato Either a b
. Non riesco a risolvere questo problema utilizzando:
f :: (Functor t, C (t (Either a b))) => t a -> Int
... perché b
non rappresenta una variabile universalmente quantificata. Né posso dire:
f :: (Functor t, C (t x)) => t a -> Int
... o utilizzare forall x
a suggerire che il vincolo è valido per tutti x
.
Quindi la mia domanda è se c'è un modo per dire che un vincolo è polimorfico su alcune delle sue variabili di tipo.
presumo che qualcosa di simile a 'classe C t dove Toint :: ta -> Int' non funziona, ed è necessario' C' per essere di tipo '* -> Vincolo'? Un polimorfismo gentile ti può aiutare? –
@ C.A.McCann Il costruttore di tipi concreti che ho in mente è 'Proxy' da' pipes' e la classe concreta è 'Monad'. Sono funzioni di utilità di classe di tipo per i tipi proxy-like, motivo per cui il vincolo è lì. Seguendo il tuo suggerimento, definirei una classe 'MonadP' specializzata nella forma del costruttore del tipo' Proxy' e la userei invece come un vincolo. Lo svantaggio è che se gli utenti volessero scrivere funzioni di utility proxy polimorfiche nel tipo proxy-like, dovrebbero rebindare la notazione per usare 'MonadP'. –
Non è possibile farlo direttamente, ma è possibile simulare, come nella risposta di Roman. Ecco il relativo ticket GHC: http://hackage.haskell.org/trac/ghc/ticket/2893 – glaebhoerl