上下文:这个问题专门提到Control.Lens (撰写本文时版本为3.9.1 )。
我一直在使用镜头库,这是非常好的,能够读和写一件作品(或为横断面)的一种结构。然后,我对镜头是否可以用来对付外部数据库进行了思考。当然,我需要在IO Monad中执行。因此,概括一下:
问题:
给定一个getter,(s -> m a)和setter (b -> s -> m t),其中m是Monad,就可以构造Lens s t a b,其中透镜的函子现在也包含了Monad?是否仍有可能用(.)与其他“纯功能”镜片组合这些镜头?
示例:
我可以用Lens (MVar a) (MVar b)
我的数据结构或多或少是这样(为了这个问题而简化的)。
data GameObject = GameObject { _num :: Int }
data Game = Game { _objects :: [GameObject] }
我使用makeLenses为这两种方法生成访问器。因此,我能够像这样进行大规模的操作:
-- loop :: MonadState with Game inside
loop = objects.traversed.num += 1
这太棒了。
但是,我无法找到一种方法来实现类似的操作(打印每个num):
game <- get
let objects
我正在寻找一个类型类似于:
Monad m => (a, b) -> (b -> m c) -> m (a, c)
在我看来,这是绑定(>>=)和晶状体手术的某种组合。
我知道我可以通过绑定后的模式匹配来解决这个问题,但是我的直觉告诉我,有一种“更简单”的方法可以通过使用镜头来编写这篇文章。
有这样的行动吗?
在使用Haskell透镜库时,我遇到了以下问题。
让我使用加布里埃尔冈萨雷斯的博客文章中的例子。
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Game = Game
{ _score :: Int
, _units :: [Unit]
, _boss :: Unit
} deriving (Show)
data Unit = Unit
{ _health :: Int
, _position :: Point
} deriving (Show)
data
我正在努力学习如何使用ST Monad。我想知道是否有可能在采取行动时打印值。例如,在Fibonacci中使用ST Monad函数
fibST :: Integer -> Integer
fibST n
| n < 2 = n
| otherwise =
runST $ do
a <- newSTRef 0
b <- newSTRef 1
go n a b
where
go 0 a _ = readSTRef a
go n a b = do
a' <
我建立了一个小游戏引擎来管理一个方块(目前用于玩康威的生活游戏)。所有的数据是通过镜头从和状态访问。引擎耦合用户输入和图形渲染(通常的游戏循环)。
帧之间的计算有时会很慢,执行时间也很长。因此,我想使用并发管理广场,使用的。
我的数据目前表示如下:
data World = World {
… -- window configuration, not important
, _squares :: TVar [Square]
}
mkLabels [''World] -- creates labels, similar to mkLenses
我的函数在Gam
我发现自己经常使用这种模式:
do
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
这似乎是Control.Lens应该能够做的事情,但我想我只是还没有找到合适的操作符。有更好的办法吗?另外,在这段代码中还有什么是我应该做的吗?
1)我需要将字段构造函数参数传递给函数。我做了一些测试,但我做不到。有可能吗?否则,有可能用镜片包吗?
2)在MonadState中是否可以使用修改来修改字段?)我做了几次尝试,但没有成功。例如:修改(第二= "x")不起作用。
import Control.Monad.State
data Test = Test {first :: Int, second :: String} deriving Show
dataTest = Test {first = 1, second = ""}
test1 = runStateT modif1 dataTest
假设我们在数据结构S a上有一个镜头[Lens' (S a) a]的列表。我想以同样的方式修改数据结构中每个镜头的焦点。 我可以这样做: s :: S a
s = _
ls :: [Lens' (S a) a]
ls = [a, b, c]
a, b, c = _
f :: a -> a
f = _
s' :: S a
s' = s
& a %~ f
& b %~ f
& c %~ f 这没问题,但是如果我有10,100个镜头呢?我想要一些像这样的东西 s' :: S a
s&
有没有一种传统的方法来映射一个使用IO的函数?具体地说,我希望映射到一个返回某种随机值的函数上。使用法线映射将产生类型(IO b)的输出,但是为了从IO解压列表中的值,我需要一个类型(IO b)的东西。所以我写了。
mapIO :: (a -> IO b) -> [a] -> [b] -> IO [b]
mapIO f [] acc = do return acc
mapIO f (x:xs) acc = do
new <- f x
mapIO f xs (new:acc)
..。它工作得很好。但是看起来Haskell应该有一个内置的解决方案。例如,一个示
我在使用和时遇到了一个问题。考虑下面的示例:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
import Control.Lens
import Control.Zipper
data A = AA { _aa :: A }
| AB { _ab :: B }
deriving (Show)
data B = B deriving (Show)
makeLenses ''A
makeLenses ''B
main :: IO ()
main =
我在使用由zoom提供的Control.Lens函数时遇到了困难。用我的自定义单变压器HearthMonad,我不知道如何满足GHC的“模棱两可的类型”的抱怨。
所讨论的代码在drawCard中。
我怎么才能解决这个问题?我是否必须创建自己的自定义缩放操作符来处理Monad m中的Hearth m
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# L
乍一看,我以为这两个函数的工作原理是一样的:
firstM _ [] = return Nothing
firstM p (x:xs) = p x >>= \r -> if r then return (Just x) else firstM p xs
firstM' p xs = fmap listToMaybe (mapM p xs)
尤其是,只要第一个p x为真,firstM就会停止。但是,由于mapM,firstM'需要对整个列表进行评估。
是否存在支持第二种定义的“惰性mapM”,或者至少有一种不需要显式递归的定义?
最近我用下面的模式编写了几次代码,我想知道是否有更短的方法来编写它。
foo :: IO String
foo = do
x <- getLine
putStrLn x >> return x
为了让事情更简洁,我写了这个函数(尽管我不确定它的名字是否合适):
constM :: (Monad m) => (a -> m b) -> a -> m a
constM f a = f a >> return a
然后我可以像这样做foo:
foo = getLine >>= constM putStrLn
像这样的函
我在Haskell有这样的代码:
import Control.Monad.Trans.State
simpleState = state (\x -> (x, x + 1))
runUntil :: (s -> Bool) -> State s a -> State s a
runUntil f s = do
s' <- get
-- Here I want to print value of s' to console
if f s'
then s >> runUntil f s
看kind of Monad
ghci>:k Monad
Monad :: (* -> *) -> Constraint
我相信这是因为它从m a获取一个m a,并返回Monad约束。
看看MonadTrans's *kind,我明白了:
ghci>:i MonadTrans
class MonadTrans (t :: (* -> *) -> * -> *) where
lift :: Monad m => m a -> t m a
-- Defined in `Control.Monad.Trans.Clas
背景:我正在创建一个有状态的游戏,用于读取和写入游戏的全局状态。
我想把我的游戏分成一些组件,比如“字符”,为这些组件提供一种与全局状态交互的特定域方式。理想情况下,这可能是定义我可以使用的表单MonadState Character m => m a的特定操作,但每个这样的m a都会对父级(全局状态)进行更改。
我已经搜索过在状态单元之间的转换,或者提供了一个从一个状态单元到另一个状态单元的接口,但是这方面的具体语言超出了我的知识范围。我也已经在使用镜片了,我想知道我是否能用它们做点什么。
编辑
我想做一些像moveCharacter :: MonadState Character m