[英]haskell — How to avoid this infinite type? (Associated data and StateT)
我想將狀態參數(狀態monad轉換器)的類型設置為該monad轉換器的關聯類型。 但是,這導致構造無限類型,
s = AssocTyp (StateT s m) a
關於為什么這不是一個真正的問題的直覺是,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a
對於所有的s
和s'
。 但是,編譯器不夠聰明,無法解決這個問題。 我讀過在某些情況下,可以使用newtype來避免無限類型; 我該怎么做?
這是重現問題的最小化代碼,
{-# LANGUAGE KindSignatures, TypeFamilies #-}
import Control.Monad.Trans.State
class MyMonad (m :: * -> *) where
data AssocTyp m :: * -> *
instance MyMonad m => MyMonad (StateT s m) where
data AssocTyp (StateT s m) a = StateTA (AssocTyp m a)
isAssocTyp :: Monad m => (AssocTyp m a) -> m ()
isAssocTyp x = return ()
x = do
v <- get
isAssocTyp (v)
我不確定你想要實現的目標。 但是,你所說的平等,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a
不是這樣,因為您使用的是數據系列而不是類型系列。 以下代碼編譯:
{-# LANGUAGE KindSignatures, TypeFamilies #-}
import Control.Monad.Trans.State
class MyMonad (m :: * -> *) where
type AssocTyp m :: * -> *
instance MyMonad m => MyMonad (StateT s m) where
type AssocTyp (StateT s m) = AssocTyp m
isAssocTyp :: Monad m => (AssocTyp m a) -> m ()
isAssocTyp x = return ()
x :: Monad m => StateT (AssocTyp m a) m ()
x = do
v <- get
isAssocTyp v
類型族和數據族之間的區別在於數據族是單射的 ,這意味着如果DF
是數據族,則以下含義成立:
DF a b c = DF a' b' c' =====> a = a', b = b', c = c'
這不是你想要的。
如果數據系列是你想要的,我有一個類型檢查的變體:
isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0 ()
isAssocType' _ = return ()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.