Это компилируется:
{-# LANGUAGE TypeFamilies, GADTs, ScopedTypeVariables #-}
-- | key
class K a where
-- | iterator for key
type I a :: *
mkI :: a -> I a
-- | A map
data M x y where
M :: K a => a -> b -> M a b
insert :: forall a b. (K a) => a -> b -> M a b -> M a b
insert = go mkI
where
go :: (a -> I a) -> a -> b -> M a b -> M a b
go o a b m = m
Что я изменил и почему?
Во-первых, я предположил, что вы хотели установить ограничение на M
, поэтому я использовал форму определения типа, которая применяет ограничение и делает его доступным на сайтах использования, GADT
.
Во-вторых, проблема, на которую жаловался ваш GHC, двусмысленность. Дело в том, что компилятор не может определить , который mkI
он должен использовать, поэтому мы должны сказать это. Для этого мы должны поместить переменные типа, используемые в области видимости, а затем указать компилятору в локальной подписи, какой экземпляр типа использовать.