Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compose tail and head

Tags:

elm

Q: elm 0.15 won't let me to (tail >> head) xs. How to solve this in an elegant way ?

module Fibonacci where

import List exposing ((::), head, map2, reverse, tail)

fibonacci : Int -> List Int
fibonacci n =
    let fibonacci' n acc =
        if n <= 2
            then acc
            else fibonacci' (n-1) ((head acc + (tail >> head) acc) :: acc)
    in
        fibonacci' n [1,1] |> reverse

Since:

head : List a -> Maybe a
tail : List a -> Maybe (List a)

I don't know how to convert Maybe (List a) to be List a

So, is there any easy way to compose these 2 function without defining a new function ?

like image 399
CodeFarmer Avatar asked Mar 25 '26 08:03

CodeFarmer


1 Answers

What you want is, technically speaking, Kleisli composition in the Maybe monad:

import List exposing (head, tail)
import Graphics.Element exposing (show)

(>=>) : (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
f >=> g = \a -> case f a of Nothing -> Nothing
                            Just b  -> g b

-- or: f >=> g = f >> (\x -> Maybe.andThen x g)

main = show ((tail >=> head) [1,2,3,4,5])

Note how the type of (>=>) is very similar to that of (>>), but all of the return types are wrapped in Maybe. You can chain arbitrary Maybe-returning functions together this way (like tail >=> tail >=> tail >=> head).

You can't type-safely convert Maybe a to a, as you'd have no option but to crash when given Nothing. You can, however, flatten a Maybe (Maybe a) value down to a Maybe a:

flattenMaybe : Maybe (Maybe a) -> Maybe a
flattenMaybe mma = 
  case mma of Just (Just a) -> Just a
              _             -> Nothing
like image 198
Lynn Avatar answered Mar 28 '26 02:03

Lynn



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!