簡體   English   中英

haskell - 如何避免這種無限類型? (相關數據和StateT)

[英]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

對於所有的ss' 但是,編譯器不夠聰明,無法解決這個問題。 我讀過在某些情況下,可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM