首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >haskell --如何避免这种无限类型?(关联数据和StateT)

haskell --如何避免这种无限类型?(关联数据和StateT)
EN

Stack Overflow用户
提问于 2012-03-27 06:19:01
回答 2查看 140关注 0票数 0

我想要将状态单体转换器的状态参数的类型设置为该单体转换器的关联类型。然而,这会导致构造一个无限类型,

代码语言:javascript
运行
复制
s = AssocTyp (StateT s m) a

为什么这不是真正的问题的直觉是,

代码语言:javascript
运行
复制
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a

用于所有ss'。然而,编译器还不够聪明,不能解决这个问题。我读到过,在某些情况下,新类型可以用来避免无限类型;我该怎么做?

下面是重现问题的最小化代码,

代码语言:javascript
运行
复制
{-# 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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-27 07:53:23

我不知道你想要达到什么目的。然而,你所说的平等,

代码语言:javascript
运行
复制
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a

不是真的,因为您使用的是数据族而不是类型族。下面的代码进行编译:

代码语言:javascript
运行
复制
{-# 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

类型族和数据族之间的区别在于data families are injective,这意味着如果DF是数据族,则以下含义成立:

代码语言:javascript
运行
复制
DF a b c = DF a' b' c'   =====>     a = a',   b = b',   c = c'

这不是你想要的情况。

票数 3
EN

Stack Overflow用户

发布于 2012-03-27 07:58:26

如果数据系列是您想要的,我有一个执行类型检查的变体:

代码语言:javascript
运行
复制
isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0 ()
isAssocType' _ = return ()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9880709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档