我如何以惯用的方式组织我的纯函数和我的单子行为
我决定今天是修复一些在单子操作中不必要运行的纯函数的日子。这就是我所拥有的。
flagWorkDays :: [C.Day] -> Handler [WorkDay]
flagWorkDays dayList =
flagWeekEnds dayList >>=
flagHolidays >>=
flagScheduled >>=
flagASAP >>=
toWorkDays
截至目前,这是 flagWeekEnds。
flagWeekEnds :: [C.Day] -> Handler [(C.Day,Availability)]
flagWeekEnds dayList = do
let yepNope = Prelude.map isWorkDay dayList
availability = Prelude.map flagAvailability yepNope
return $ Prelude.zip dayList availability
flagHolidays
遵循类似的模式。 toWorkDays
只是将一种类型更改为另一种类型,并且是一个纯函数。
flagScheduled
和 flagASAP
是单子操作。我不确定如何在 flagWorkDays
中将单子操作与纯函数惯用地结合起来。假设 flagWeekEnds
和 flagHolidays
已变得纯净,有人可以帮我修复 flagWorkDays
吗?
I've decided today is the day I fix some of my pure functions that are unnecessarily running in a monadic action. Here's what I have.
flagWorkDays :: [C.Day] -> Handler [WorkDay]
flagWorkDays dayList =
flagWeekEnds dayList >>=
flagHolidays >>=
flagScheduled >>=
flagASAP >>=
toWorkDays
Here is flagWeekEnds, as of now.
flagWeekEnds :: [C.Day] -> Handler [(C.Day,Availability)]
flagWeekEnds dayList = do
let yepNope = Prelude.map isWorkDay dayList
availability = Prelude.map flagAvailability yepNope
return $ Prelude.zip dayList availability
flagHolidays
follows a similar pattern. toWorkDays
just changes one type to another, and is a pure function.
flagScheduled
, and flagASAP
are monadic actions. I am not sure how to combine the monadic actions with the pure functions idiomatically in flagWorkDays
. Could someone help me fix flagWorkDays
, assuming flagWeekEnds
and flagHolidays
have been made pure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
让我们退后一步。您有两种类型的函数,其中一些是纯函数,其类型为
a ->; b
,以及一些a -> 类型的单子m b
。为了避免混淆,我们也坚持从右到左的构图。如果您喜欢从左到右阅读,只需颠倒函数的顺序并将
(<=<)
替换为(>=>)
,以及来自Control.Arrow
的(.)
和(>>>)
。那么如何组合它们有四种可能性。
纯粹再纯粹。使用常规函数组合
(.)
。纯粹然后一元。还可以使用
(.)
.一元然后一元。使用 kleisli 组合
(<=<)
。Monadic then pure。在纯函数上使用
fmap
并使用(.)
进行组合。忽略所涉及类型的细节,您的功能是:
让我们从顶部开始。
flagWeekEnds
和flagHolidays
都是纯的。情况1.这是纯粹的。接下来是
flagScheduled
,它是一元的。情况 2.接下来是
flagASAP
,现在我们有两个一元函数。情况 3。最后,我们有纯函数
toWorkDays
。案例 4.我们就完成了。
Let's take a step back for a moment. You have two types of functions, some pure with types of the form
a -> b
, and some monadic of typea -> m b
.To avoid confusion, let's also stick with right-to-left composition. If you prefer to read left-to-right, just reverse the order of the functions and replace
(<=<)
with(>=>)
, and(.)
with(>>>)
fromControl.Arrow
.There are then four possibilities for how these can be composed.
Pure then pure. Use regular function composition
(.)
.Pure then monadic. Also use
(.)
.Monadic then monadic. Use kleisli composition
(<=<)
.Monadic then pure. Use
fmap
on the pure function and(.)
to compose.Ignoring the specifics of the types involved, your functions are:
Let's go from the top.
flagWeekEnds
andflagHolidays
are both pure. Case 1.This is pure. Next up is
flagScheduled
, which is monadic. Case 2.Next is
flagASAP
, now we have two monadic functions. Case 3.And finally, we have the pure function
toWorkDays
. Case 4.And we're done.
为了填写 FUZxxl 的答案,让我们纯化
flagWeekEnds
:您经常在变量名称后放置一个“s”(
day
->days
)一个列表(就像英语中的复数形式一样)。To fill in FUZxxl's answer, let's pureify
flagWeekEnds
:You often put an "s" after variable names (
day
->days
) when its a list (as you do with plural in English).这不是很困难。您基本上只需将
(>>=)
替换为(.)
并翻转操作数顺序即可。do
语法可能有助于澄清。我还使用 Kleisli 组合器 (fish)(<=<) :: (b -> mc) -> 将示例设为 pointfree。 (a→mb)→一个-> m c
,本质上是 monad 的(.)
。It's not very difficult. You basically just replace
(>>=)
by(.)
and flip the operands order.do
syntax may help to clarify. I also made the example pointfree using the Kleisli combinator (fish)(<=<) :: (b -> m c) -> (a -> m b) -> a -> m c
, that is essentially(.)
for monads.