如何整理我的纯函数与我的单子行动惯用
今天我决定是一天我解决一些被不必要地在一元行动运行我的纯函数。这是我的。如何整理我的纯函数与我的单子行动惯用
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
中将monadic操作与纯函数惯用地结合起来。假设flagWeekEnds
和flagHolidays
已经被做成纯的,有人能帮我修复flagWorkDays
吗?
让我们退一步了一会儿。您有两种类型的功能,其中一些类型为a -> b
,一些类型为a -> m b
。
为了避免混淆,我们还要坚持从右到左的组合。如果你喜欢阅读左到右,只是反转的功能的顺序和Control.Arrow
与(>>>)
取代(<=<)
与(>=>)
和(.)
。
有那么对于如何将这些由四种可能性。
-
纯则纯。使用常规功能组合
(.)
。g :: a -> b f :: b -> c f . g :: a -> c
-
纯然后单子。也使用
(.)
。g :: a -> b f :: b -> m c f . g :: a -> m c
-
单子然后单子。使用kleisli组成
(<=<)
。g :: a -> m b f :: b -> m c f <=< g :: a -> m c
-
单子然后纯。在纯功能上使用
fmap
,并使用(.)
来组成。g :: a -> m b f :: b -> c fmap f . g :: a -> m c
忽略所涉及的类型的细节,你的职责是:
flagWeekEnds :: a -> b
flagHolidays :: b -> c
flagScheduled :: c -> m d
flagASAP :: d -> m e
toWorkDays :: e -> f
让我们从上面走。 flagWeekEnds
和flagHolidays
都是纯的。案例1.
flagHolidays . flagWeekEnds
:: a -> c
这是纯粹的。接下来是flagScheduled
,这是monadic。情况2.
flagScheduled . flagHolidays . flagWeekEnds
:: a -> m d
接下来是flagASAP
,现在我们有两个monadic函数。案例3.
flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds
:: a -> m e
最后,我们有纯功能toWorkDays
。情况4.
fmap toWorkDays . flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds
:: a -> m f
我们完成了。
这不是很困难的。您基本上只需将(>>=)
替换为(.)
并翻转操作数顺序。语法可能有助于澄清。我也使用Kleisli combinator(鱼)(<=<) :: (b -> m c) -> (a -> m b) -> a -> m c
,这基本上是(.)
单子的例子pointfree。
import Control.Monad
flagWorkDays :: [C.Day] -> Handler [WorkDay]
flagWorkDays =
fmap toWorkDays . flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds
为了填补FUZxxl的回答,让我们pureify flagWeekEnds
:
flagWeekEnds :: [C.Day] -> [(C.Day,Availability)]
flagWeekEnds days = days `zip` map (flagAvailability . isWorkDay) days
你经常把一个 “s” 变量名之后(day
- >days
)时,其列表(如你有多个办用英语)。
+1一般说明 – fuz
一如既往的辉煌。 – Ingo