I have this code:
{-# LANGUAGE RankNTypes, MultiParamTypeClasses, FlexibleInstances, TypeFamilies, TypeOperators, DataKinds, StandaloneKindSignatures, FlexibleInstances, QuantifiedConstraints, FlexibleContexts, ConstraintKinds, KindSignatures, ScopedTypeVariables, UndecidableInstances, MultiParamTypeClasses, GADTs, ExistentialQuantification, TupleSections, NamedFieldPuns, UnicodeSyntax, PolyKinds, LambdaCase, PartialTypeSignatures, KindSignatures, TypeFamilyDependencies, UndecidableSuperClasses, FunctionalDependencies, ImpredicativeTypes, UnicodeSyntax, AllowAmbiguousTypes #-}
import Data.Either
type CSat = () :: Constraint
type CNSat = Int ~ Bool
type family OfKind a b where
OfKind a (b :: a) = CSat
OfKind a (b :: m) = CNSat
type family OfType a b where
OfType a a = CSat
OfType a b = CNSat
fu :: OfKind * t => t -> t
fu = id
_ = fu 0 -- Ok, Int is *
_ = fu Either -- OK???? WUTTTT????!!!!!! Either is * -> * -> *
The most fun answer is ‘why does this compile?’. It contradicts my intuition since I expect Either
to not be *, do you know what is going on here?
Is it because with poly kinds haskell treats everything as *?