Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applicative functors within lambda expressions, non-exhaustive patterns?

I'm testing out applicative functors in lambda functions, but I'm stuck with the below code I've written. 'myAddition' need to take the cumulative total of 'Random a':

I appreciate there are better ways to do the below, however I'm learning functors so this is relevant

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

The error:

"Non-exhaustive patterns in function <*>"

I understand what the error means, however I'm unsure how to make the applicative functor lambda exhaustive?

like image 854
Babra Cunningham Avatar asked Aug 09 '26 06:08

Babra Cunningham


1 Answers

Here's one way you can solve this:

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

First, bring into the format f (a -> b) <*> f a) and define result for first case as Random (f a). Then, handle the case where your input is Nill by setting the result to Nill, regardless of the f (a -> b) and f a terms. This will address all possible values for the Random constructor and solve your non-exhaustive pattern problem.

Alternatively, you may choose to break the cases down further like so, with the same result:

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

Demo

like image 122
shree.pat18 Avatar answered Aug 13 '26 14:08

shree.pat18



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!