Control.Lens.Fold包含filtered
,我可以用来在应用一些monadic动作之前过滤列表.似乎没有相应的filteredM
- 但有没有办法达到这个效果?
要清楚,说我有
xs :: [ MyType ]
predM :: MyType -> MyMonad Bool
actionM :: MyType -> MyMonad ()
Run Code Online (Sandbox Code Playgroud)
我怎么能申请actionM
到的每个元素xs
这对于predM
返回True
?
一个重要的约束是我想predM
在第一次调用之前对所有调用进行排序actionM
- 所以我需要一种方法在列表上进行两次传递.我不能只是结合predM
并actionM
成一个单一的功能.
我有一个数据结构,可以理解为类似于将Data.Map
一种类型的键映射到另一种类型的值.我想写一个Control.Lens.At
这种类型的实例,但我似乎无法满足所有要求.
由于Struct k v
有lookup
,insert
,update
,和delete
,我必须做什么做instance At (Struct k v)
的工作?
我有另一个库中定义的数据类型.我想用Control.Lens库生成的镜头挂钩到该数据类型.
我是否需要在我的代码中使用newtype我的类型,或者认为已经定义的数据类型是否安全?
我想在有状态计算中使用相同的镜头作为setter和getter.似乎GHC无法推断出Functor f的常见类型.
import Lens.Family
import Lens.Family.State
import Control.Monad.State
-- | Run computation inside modified state
with :: Functor f => LensLike' f s a -> a -> State s b -> State s b
with lens value comp = do
value' <- use lens
lens .= value
res <- comp
lens .= value'
return res
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,是否有可能实现这样的行为,还是应该使用单独的镜头作为制定者和吸气剂?谢谢!
我是镜头的新手,我想组成两个"setter"操作,等同于state0到new_state2的转换:
let new_state1 = field1 %~ (const newVal1) $ state0
let new_state2 = field2 %~ (const newVal2) $ new_state1
Run Code Online (Sandbox Code Playgroud)
这样做的语法是什么?
从这种Getter
类型开始
type Getter s a = forall r. (a -> Const r a) -> s -> Const r s
Run Code Online (Sandbox Code Playgroud)
我们需要一个额外的Monoid
约束来获得Fold
:
type Fold s a = forall r. Monoid r => (a -> Const r a) -> s -> Const r s
Run Code Online (Sandbox Code Playgroud)
但是Fold
的实际和更一般的类型是
type Fold s a = forall f. (Contravariant f, Applicative f) => (a -> f a) -> s -> f s
Run Code Online (Sandbox Code Playgroud)
我了解这Contravariant
是用来排除的Identity
,因此确保我们只能获得价值。但是我不明白怎么Monoid r
对应Applicative …
有什么办法可以用镜头写下以下内容...
[Maybe Text] -> Text
Run Code Online (Sandbox Code Playgroud)
...可能可以概括为:
(Monoid a, Traversable t) => t a -> a
Run Code Online (Sandbox Code Playgroud)
我正在尝试做的一个具体示例:
[Just "abc", Nothing, Just "def"] -> "abcdef"
[Nothing, Nothing] -> ""
Run Code Online (Sandbox Code Playgroud)
PS:我假设镜头有一些时髦的组合器可以做到这一点。如果我对镜头的超凡能力感到迷惑,并且可以通过更简单的组合器轻松实现,请告诉我。
当输入值(未设置字段)为?时,是否有任何方法可以应用Control-Lens-Setter.html#g:4中提到的组合器/设置器?Just x
例如,考虑(~+)
组合器,如果我具有以下条件:
let target = (1, 2)
input1 = Just 10
input2 = Nothing
Run Code Online (Sandbox Code Playgroud)
我想要一个执行以下操作的设置器:
(11, 2) == target & (_1 . someSetter) +~ input1
& (_2 . someSetter) +~ input2
Run Code Online (Sandbox Code Playgroud)
我尝试避免使用fmap
或maybe/fromMaybe
在这种情况下使用,因为我有很多此类操作要做,并且我更喜欢通过利用镜片的简洁/简洁来避免样板。
我有这个文件:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ExistentialQuantification #-}
module Toy where
import Control.Lens
data Bar = Bar { _barish :: String }
data Foo = forall a. Show a => Foo { _fooish :: a }
$(makeLenses ''Bar)
$(makeLenses ''Foo)
x = barish
y = fooish
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
Toy.hs:15:5:
Not in scope: `fooish'
Perhaps you meant `_fooish' (line 9)
Run Code Online (Sandbox Code Playgroud)
这是我第一次尝试使用存在量词; 我不知道为什么这些功能组合会中断.更令人担忧的是,为什么我没有收到有关makeLenses失败的错误消息?我跑了runhaskell Toy.hs
我有这些类型(还有更多):
data Player = PlayerOne | PlayerTwo deriving (Eq, Show, Read, Enum, Bounded)
data Point = Love | Fifteen | Thirty deriving (Eq, Show, Read, Enum, Bounded)
data PointsData =
PointsData { pointsToPlayerOne :: Point, pointsToPlayerTwo :: Point }
deriving (Eq, Show, Read)
Run Code Online (Sandbox Code Playgroud)
我正在做Tennis kata,作为实现的一部分,我想使用一些函数,这些函数使我能够为任意播放器获取或设置积分,只有在运行时才能知道。
正式地,我需要像这样的功能:
pointFor :: PointsData -> Player -> Point
pointFor pd PlayerOne = pointsToPlayerOne pd
pointFor pd PlayerTwo = pointsToPlayerTwo pd
pointTo :: PointsData -> Player -> Point -> PointsData
pointTo pd PlayerOne p …
Run Code Online (Sandbox Code Playgroud)