gpt4 book ai didi

haskell - 隐藏 State monad 的类型参数

转载 作者:行者123 更新时间:2023-12-04 13:59:01 24 4
gpt4 key购买 nike

我试图隐藏 State 的类型参数monad 是一种新类型,但我很难统一存在限定的 sg提供给 evalFoo .我试过 ExistentialQuantification , GADTs , 和 RankNTypes ,但对这些扩展的工作原理的理解确实很差。

惯用的 Haskell 方法将如何完成这种外观?
谢谢!

{-# LANGUAGE GADTs #-}

import Control.Monad.State
import System.Random

data Foo a where
Foo :: RandomGen s => State s a -> Foo a

evalFoo :: RandomGen g => Foo a -> g -> a
evalFoo (Foo m) g = evalState m g

目标是实现这样的目标,但能够提供 RandomGen 的任何实例:
myRNG :: Foo Double
myRNG = Foo $ do
u <- state random
return u

Prelude> evalFoo myRNG (mkStdGen 123)
0.7804356004944119

最佳答案

Foo 类型的存在量化构造函数意味着对于 Foo 类型的每个值,有一些 RandomGen 的实例它用作它的状态。但是,您想要相反的结果:您想要给定任何值 foo :: Foo , 和 任意 实例 gRandomGen , 你可以使用 g作为 foo 封装的计算状态.

所以让我们改写:

{-# LANGUAGE Rank2Types #-}

import Control.Monad.State
import System.Random

newtype Foo a = MkFoo{ unFoo :: forall g. (RandomGen g) => State g a }

evalFoo :: RandomGen g => Foo a -> g -> a
evalFoo = evalState . unFoo

这可以按预期使用:
myRNG :: Foo Double
myRNG = MkFoo $ do
u <- state random
return u

给予
*Main> evalFoo myRNG (mkStdGen 123)
0.43927189736460226

是的,不完全是 0.78 ;)

关于haskell - 隐藏 State monad 的类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34327356/

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