gpt4 book ai didi

haskell - 为 STT 定义 PrimMonad 实例? (意法半导体变压器)

转载 作者:行者123 更新时间:2023-12-02 04:09:14 26 4
gpt4 key购买 nike

Data.Vector.Mutable 似乎需要 ST IO monad 中的 PrimMonad 实例。

类型类定义如下 --

-- | Class of primitive state-transformer monads
class Monad m => PrimMonad m where
-- | State token type
type PrimState m

-- | Execute a primitive operation
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a

-- | Expose the internal structure of the monad
internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)

它们是这样实现的——

instance PrimMonad IO where
type PrimState IO = RealWorld
primitive = IO
internal (IO p) = p

instance PrimMonad (ST s) where
type PrimState (ST s) = s
primitive = ST
internal (ST p) = p

我根本不明白类型类的任何函数应该做什么,或者实现如何工作。

但我需要为 STT 实现它(http://hackage.haskell.org/package/STMonadTrans-0.3.1 给出的那个)

STT 有构造函数 STT s m a

在我天真的尝试中,我尝试将所有 ST s 替换为 STT s m:

instance Monad m => PrimMonad (STT s m) where
type PrimState (STT s m) = s
primitive = STT
internal (STT p m) = p

但我收到此错误:

Not in scope: data constructor `STT'

对于primitiveinternal的定义,尽管已经在整个程序中多次使用了STT(尽管我猜作为类型构造函数) ?)。

我应该如何正确实现这个类型类?

(我最终将使用它作为STT s (R​​and g) a)

<小时/>

编辑:我导入了 Control.Monad.ST.Trans.Internal 以获取 STT 作为数据构造函数,这些是新错误:(更改 内部(STT s m)内部(STT s))

Couldn't match kind `*' against `ArgKind'
Kind incompatibility when matching types:
m0 :: * -> *
(#,#) (ghc-prim:GHC.Prim.State# (PrimState (STT s m))) :: ArgKind
-> (#)
In the expression: STT
In an equation for `primitive': primitive = STT


Couldn't match type `m'
with `(#,#) (ghc-prim:GHC.Prim.State# (PrimState (STT s m)))'
`m' is a rigid type variable bound by
the instance declaration at src/pimc/PIMC.hs:41:16
Expected type: ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
Actual type: ghc-prim:GHC.Prim.State# s -> m (STTRet s a)
In the expression: p
In an equation for `internal': internal (STT p) = p



Couldn't match type `a' with `STTRet s a'
`a' is a rigid type variable bound by
the type signature for
internal :: STT s m a
-> ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
at src/pimc/PIMC.hs:44:3
Expected type: ghc-prim:GHC.Prim.State# (PrimState (STT s m))
-> (# ghc-prim:GHC.Prim.State# (PrimState (STT s m)), a #)
Actual type: ghc-prim:GHC.Prim.State# s -> m (STTRet s a)
In the expression: p
In an equation for `internal': internal (STT p) = p

最佳答案

原则上,您可能能够为原语编写实现,但不能为内部编写实现,因为它为您的 monad 强加了某种结构,而这只能由 IO 和 ST monad 的内部实现来满足。

但是,我的印象是问题出在 Data.Vector.Mutable 模块上,它的要求过于严格。例如,要在 monad m 中使用 IO Vector,原则上只需要将 IO 嵌入到 m 中(即原始方法),反之亦然(即内部方法)。如果这是正确的,他们应该尝试将 PrimMonad 类分割为嵌入部分和同构部分,例如如下:

-- | Class of primitive state-transformer monads
class Monad m => PrimMonadEmbed m where
-- | State token type
type PrimState m

-- | Execute a primitive operation
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a

class PrimMonadEmbed m => PrimMonad m where
-- | Expose the internal structure of the monad
internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)

这在向后兼容性方面可能没问题,因为用户代码中不能存在自定义实例。降低要求也将使他们的代码可用于 IO monad 的转换版本,如 StateT Int IO 等。

您可以尝试两件事:

  • 实现 PrimMonad 的部分实例,仅实现原始方法并让内部抛出错误,看看是否可以像这样使用向量库
  • 联系您正在使用的矢量库的作者,询问他们上述建议是否现实......

顺便说一句,以下原语实现应该可以工作(比较 STT 的源代码以了解代码中出了什么问题):

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}

module Test where

import Control.Monad.Primitive
import Control.Monad.ST.Trans
import Control.Monad.ST.Trans.Internal

instance Monad m => PrimMonad (STT s m) where
type PrimState (STT s m) = s
primitive f = STT (\s -> case (f s) of (# s', v #) -> return (STTRet s' v))
internal _ = error "no implementation of internal for STT"

关于haskell - 为 STT 定义 PrimMonad 实例? (意法半导体变压器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17522198/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com