将混合类型(可能是适用类型)的参数应用于函数的最佳方法

问题描述 投票:1回答:1

我对Haskell和函数式编程还很陌生,最近我正在学习有关函子,应用程序和Monad的知识。虽然我似乎了解一些基础知识,但是当某些参数的类型更改为Applicative时,我很难找出最好/最惯用的方法应用函数参数。考虑下面的简单代码:

myfun :: Int -> Int -> Int -> Int
myfun a b c = a + b + c             -- lets pretend this does something more complicated

a = 5
b = 10
c = 20

result = myfun a b c

使用myfun计算结果非常简单。但是,随着需求的变化,我们的输入abc可能会更改为Maybe Int[Int],而不是Int。通过执行以下操作之一,我们仍然可以使用未经修改的myfun

result = myfun <$> a <*> b <*> c   -- either like this
result = liftA3 myfun a b c        -- or like that

但是,实际上,参数abc可能不会总是最终落在同一Applicative中,因此上述两种方法将不起作用。在不修改myfun功能的情况下最好的方法是什么?请考虑以下abc的方案:

  • 有些是Int,有些是Maybe Int(应用程序的结果为Maybe Int
  • [有些是Maybe Int,有些是Either String Int(结果可能是Maybe IntEither String Int,如果有任何参数是NothingLeft,则语义将使计算短路)]
  • 有些是[Int],有些是Maybe Int(结果应该是Maybe [Int],其语义是像所有参数都是[Int]一样计算所有可能的组合,然后将其包装在Just内,除非在Maybies是Nothing,在这种情况下,我们短路到Nothing

非常感谢任何见解!

haskell applicative
1个回答
0
投票

取决于您要发生的事情。可能没有任何通用的方法可以组合不同的单子。通常,当您确实需要组合不同的monad时,您可以经常(总是?)使用monad变压器,但是通常有更简单的解决方案。您提到的特定组合就是这种情况。

在所有这些特定情况下,您都可以将一个单子转换为另一个。在下文中,我将给出一些可以完成此操作的示例。

其中一些示例使用了Data.Maybe中的函数,因此我将从以下内容开始:

import Data.Maybe

在第一个示例中不是必需的,但在第二个和第三个示例中将是必需的。

一些Int,一些Maybe Int

如果您具有IntMaybe Int值的组合,则解决方案很简单。只需将Int值提升到Maybe Int。您可以为此使用Justpure。这是使用pure的示例:

a1 = 5
b1 = Just 10
c1 = 20

result1 :: Maybe Int
result1 = myfun <$> pure a1 <*> b1 <*> pure c1

结果为Just 35

一些Maybe Int,一些Either String Int

您可以通过将单子转换为另一种来重复此技巧。如果您有很好的Maybe Int值可用于Either String Int情况,则可以将String值转换为Nothing值。您也可以通过丢弃Either String Int值将Maybe Int值转换为String值。

这是将Maybe Int转换为Either String Int的示例:

a2 = Just 5
b2 = Right 10
c2 = Left "Boo!"

result2 :: Either String Int
result2 = myfun <$> maybe (Left "No value") Right a2 <*> b2 <*> c2

此组合使用maybe中的Data.Maybe功能。结果为Left "Boo!"

一些[Int],一些Maybe Int

您可以使用Maybe Int轻松地将[Int]转换为maybeToList

a3 = [5, 10]
b3 = Nothing
c3 = Just 20

result3 :: [Int]
result3 = myfun <$> a3 <*> maybeToList b3 <*> maybeToList c3

这样做的结果是[],因为Nothing转换为[],这就是Applicative用于列表的方式。这可能不是您想要的,但我希望这些示例可以启发您提出自己想要的构图。

© www.soinside.com 2019 - 2024. All rights reserved.