【问题标题】:Applicative functors within lambda expressions, non-exhaustive patterns?lambda 表达式中的应用函子,非穷举模式?
【发布时间】:2016-10-10 09:07:56
【问题描述】:

我正在测试 lambda 函数中的应用函子,但我坚持使用我编写的以下代码。 'myAddition' 需要取'Random a' 的累计总数:

我很欣赏下面有更好的方法,但是我正在学习函子,所以这是相关的

data Random a = Nill | Random a deriving (Show, Ord, Eq)

randomOrNot = [Nill, Random 22, Random 101, Nill, Random 44]

instance Functor Random where
  fmap f (Nill) = Nill
  fmap f (Random a) = Random (f a)

instance Applicative Random where
  pure a = Random a
  (<*>) (Random a) = fmap a

cumulativeTotal :: [Random a] -> Random a
cumulativeTotal li = foldr (\el acc -> (pure (+) <*> el) <*> acc) (Random 0) li

main = do
  print $ cumulativeTotal randomOrNot

错误:

"Non-exhaustive patterns in function <*>"

我了解错误的含义,但是我不确定如何使应用函子 lambda 详尽无遗?

【问题讨论】:

  • 应用到Nill上应该怎么办?
  • 您没有在Applicative Random 实例中处理(&lt;*&gt;) Nill 的情况。
  • 你的Random类型只是Maybe的伪装。

标签: haskell lambda applicative


【解决方案1】:

这里有一种方法可以解决这个问题:

 instance Applicative Random where
     pure a = Random a
     (Random f) <*> (Random a) = Random (f a)
     _ <*> _ = Nill

首先,导入格式f (a -&gt; b) &lt;*&gt; f a),并将第一种情况的结果定义为Random (f a)。然后,无论f (a -&gt; b)f a 条款如何,通过将结果设置为Nill 来处理输入为Nill 的情况。这将解决 Random 构造函数的所有可能值并解决您的非详尽模式问题。

或者,您可以选择像这样进一步分解案例,结果相同:

instance Applicative Random where
    pure a = Random a
    (Random f) <*> (Random a) = Random (f a)
    _ <*> Nill = Nill
    Nill <*> (Random a) = Nill

Demo

【讨论】:

  • 如果我想跳过/忽略 Nill 值怎么办?否则,使用上述解决方案,Nill 值的任何实例都会导致累积输出为 Nill。
  • 那么对于给定的输入,您的预期输出是什么样的?
  • [Nill, Random 2, Random 4] = Random 6(相对于您的解决方案 = Nill)
  • 我不确定这种跳过是否可行。基于类型签名,输出只能是 Random x 或 Nill,除非您在第一种情况下以某种方式注入另一个类似于 f 的术语,否则任何操作都不会满足类型条件(类型 f b 的输出,其中 b 与 a 不同)
  • @barbrac 正如 shree.pat18 所说,这是不可能的。另一种方法是为您的类型实现Alternative(参见Data.Foldable 中的asum)。
猜你喜欢
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多