gpt4 book ai didi

haskell - 如何以及何时使用 State functor 和 State applicative?

转载 作者:行者123 更新时间:2023-12-04 02:27:39 25 4
gpt4 key购买 nike

我见过 MaybeEither在代码中使用仿函数(和应用)是有道理的,但我很难想出一个 State 的例子。仿函数和应用。也许它们不是很有用,只是因为 State 才存在。 monad 需要一个仿函数和一个应用程序?关于它们的实现有很多解释,但在代码中使用它们时没有任何示例,因此我正在寻找有关它们如何单独使用的说明。

最佳答案

我能想到几个例子。
一、 State 的一种常见用途是为了使某些“标识符”集变得独特而管理计数器。所以,状态本身是一个 Int ,主要的原始状态操作是检索计数器的当前值并递增它:

-- the state
type S = Int

newInt :: State S Int
newInt = state (\s -> (s, s+1))
仿函数实例是对不同类型的标识符使用相同计数器的简洁方式,例如某些语言中的术语和类型级变量:
type Prefix = String
data Var = Var Prefix Int
data TypeVar = TypeVar Prefix Int
您可以在其中生成新的标识符,如下所示:
newVar :: Prefix -> State S Var
newVar s = Var s <$> newInt

newTypeVar :: Prefix -> State S TypeVar
newTypeVar s = TypeVar s <$> newInt
applicative 实例有助于编写由此类唯一标识符构造的表达式。例如,我在编写类型检查器时经常使用这种方法,它通常会使用新变量构造类型,如下所示:
typeCheckAFunction = ...
let freshFunctionType = ArrowType <$> newTypeVar <*> newTypeVar
...
在这里, freshFunctionType是新的 a -> b带有新鲜类型变量的样式类型 ab这可以传递到统一步骤。
第二 State的另一种用途是管理随机数生成的种子。例如,如果你想要一个低质量但超快的 LCG 生成器,你可以这样写:
lcg :: Word32 -> Word32
lcg x = (a * x + c)
where a = 1664525
c = 1013904223

-- monad for random numbers
type L = State Word32

randWord32 :: L Word32
randWord32 = state $ \s -> let s' = lcg s in (s', s')
仿函数实例可用于修改 Word32使用纯转换函数的输出:
randUniform :: L Double
randUniform = toUnit <$> randWord32
where toUnit w = fromIntegral w / fromIntegral (maxBound `asTypeOf` w)
而 applicative 实例可用于编写依赖于多个 Word32 的原语。输出:
randUniform2 :: L (Double, Double)
randUniform2 = (,) <$> randUniform <*> randUniform
和以相当自然的方式使用随机数的表达式:
-- area of a random triangle, say
a = areaOf <$> (Triangle <$> randUniform2 <*> randUniform2 <$> randUniform2)

关于haskell - 如何以及何时使用 State functor 和 State applicative?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66355475/

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