2015-08-19 1 views
3

Q: elm 0.15 ne me laissera pas (tail >> head) xs. Comment résoudre cela d'une manière élégante?composer la queue et la tête

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 

depuis:

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

Je ne sais pas comment convertir Maybe (List a) to be List a

Alors, est-il un moyen facile de composer ces deux fonctions sans définir une nouvelle fonction?

+2

Il est difficile de dire, mais si cette question ne concerne pas Haskell, s'il vous plaît enlever l'étiquette Haskell de lui. – Lynn

+2

@Mauris Les gens ajoutent occasionnellement [haskell] à des questions sur les langages inspirés de Haskell comme Elm ou PureScript dans l'espoir de trouver un public plus large de personnes capables d'aider. Je n'ai pas d'opinion arrêtée sur la question de savoir si c'est acceptable ou non. – duplode

+1

Bien qu'il ne s'agisse pas d'une réponse à la question "Comment composer" head' et "tail", si vous voulez vraiment savoir "comment puis-je obtenir la somme des 2 premiers nombres dans un" numéro de liste "? , quand je sais qu'il y a au moins 2 éléments dans la liste? ", alors' take 2 >> sum' fonctionnera pour votre cas.voir: https://gist.github.com/robertjlooby/1950525cb9a4745ecc2d – robertjlooby

Répondre

6

Ce que vous voulez est, techniquement parlant, Kleisli composition dans la monade Peut-être:

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]) 

Notez comment le type de (>=>) est très similaire à celle de (>>), mais tous les types de retour sont enveloppé dans Maybe. Vous pouvez chaîner des fonctions arbitraires Maybe de cette manière (comme tail >=> tail >=> tail >=> head).

Vous ne pouvez pas taper en toute sécurité Maybe a à a, car vous n'auriez pas d'autre choix que de planter quand vous le recevrez Nothing. Vous pouvez , cependant, aplatir une valeur Maybe (Maybe a) jusqu'à un Maybe a:

flattenMaybe : Maybe (Maybe a) -> Maybe a 
flattenMaybe mma = 
    case mma of Just (Just a) -> Just a 
       _    -> Nothing 
+0

"f> => g = f >> Maybe.andThen g "a une erreur sur elm 0.15 Conflit entre" Maybe b "et" a -> Maybe b " – CodeFarmer