haskell - 广义新型推导

标签 haskell monads state-monad deriving newtype

Haskell 可以导出 MonadState s 的实例在 T1低于但不在 T2然而,这是一个非常相似的类型。我应该以哪种方式修改 T2 的代码?以便 MonadState s 的实例可以自动导出吗?

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.Reader
import Control.Monad.State

newtype T1 r s a = 
  T1 { runT1 :: ReaderT r (State s) a }
  deriving (Monad, MonadReader r, MonadState s)

newtype T2 r s a = 
  T2 { runT2 :: StateT r (State s) a }
  deriving (Monad, MonadState r, MonadState s)

最佳答案

MonadState 的类型不能有两个实例.这是因为 MonadState定义为

class Monad m => MonadState s m | m -> s where
    get :: m s
    set :: s -> m ()
    state :: (s -> (a, s)) -> m a

关键部分是| m -> s .这需要扩展名 FunctionalDependencies ,并声明对于任何 m ,我们自动知道关联的s .这意味着对于任何给定的 m , s 只能有一种选择这是有效的。所以你不能让它同时适用于 MonadState r mMonadState s m除非r ~ s .如果 r ~ s ,那么编译器如何知道它适用于哪个底层 monad?在这种情况下,我想你也会发现如果你创建 get 代码会更容易理解和使用。和 put带有后缀的函数,例如 getInner , setInnergetOuter , setOuter .

关于haskell - 广义新型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25693483/

相关文章:

algorithm - 你会如何在 Haskell 中表达它?

c - 过程式语言和函数式语言之间的区别?

Haskell:运行两个单子(monad),保留第一个的结果

haskell - 为什么状态单子(monad)通常使用 newtype 而不是 type

Haskell - 混合状态计算

algorithm - 我的边界框功能哪里出了问题?

haskell - Haskell 的 Lazy 和 Strict monad(或变形金刚)之间的区别

Haskell 列表理解和列表 Monad

haskell - 如何处理 Gtk2Hs 中的应用程序状态

haskell - 如何在 Haskell 中使用 IO 制作随机列表