2017-08-14 1 views
0

Je n'ai pas la moindre idée comment convertir une valeur peut-être à une valeur normale ...La conversion d'une valeur Peut-être en une valeur normale

Je ces lignes ...

pickChord : Model -> Note -> Chord 
pickChord model note = 
    let 
     nextChord = List.head (List.filter (testChord note) model.possibleMajorChords) 
    in 
     nextChord 

Le compilateur se plaint:

La définition de pickChord ne correspond pas à son annotation de type. - L'annotation de type pour pickChord dit qu'il revient toujours:

Chord

Mais la valeur retournée (ci-dessus) est un:

Peut-être Chord

Comment pourrais-je gérer ce problème?

Merci.

Répondre

2

C'est pourquoi j'aime Elm. À sa façon, Elm vous dit que vous avez un défaut de conception.

Regardons de plus près. Voici le code tel quel:

pickChord : Model -> Note -> Chord 
pickChord model note = 
    let 
     nextChord = List.head (List.filter (testChord note) model.possibleMajorChords) 
    in 
     nextChord 

Vous avez une liste d'accords majeurs que vous puis filtre pour une note spécifique. Cela produit un List d'accords. Cependant, le type List peut représenter une liste vide, c'est pourquoi List.head renvoie Maybe. Dans votre cas, List.head peut renvoyer un Nothing ou Just Chord.

Maintenant, vous pouvez travail autour de cela avec les valeurs par défaut et la gestion des erreurs, mais ce sont contournements juste qui esquiver le vrai problème: Le type de liste ne correspond pas avec précision votre domaine de problème.

Si vous avez une liste de tous les les accords majeurs, je ne peux pas penser à une raison pour laquelle vous finiriez jamais avec une liste vide après application du filtre. Le filtre doit toujours trouver au moins un accord. En supposant que c'est le cas, ce dont vous avez besoin est un type semblable à List qui peut représenter une liste jamais vide; Ce qui signifie que head retournera toujours un Chord et non un Maybe Chord. Ce serait une meilleure représentation de ce que vous essayez d'accomplir.Heureusement, il existe déjà un tel type (que je n'ai pas créé mais que j'utilise beaucoup) appelé List.Nonempty. Voici comment cela fonctionnerait:

import List.Nonempty as NE 

pickChord : Model -> Note -> Chord 
pickChord model note =   
    NE.head (NE.filter (testChord note) model.possibleMajorChords) 

Votre model.possibleMajorChords faudrait passer d'un List Chord à un List.Nonempty Chord, mais il fait tout le problème peut-être aller. C'est supposer bien sûr que ma revendication sur le filtre retournant toujours au moins un accord est vraie.

est ici un lien vers le paquet non vide: http://package.elm-lang.org/packages/mgold/elm-nonempty-list/latest

+0

en fait ... filtre nécessite une valeur par défaut. Donc, vous pouvez avoir besoin d'un type différent, mais le point est List n'est probablement pas. –

2

Si vous avez une liste de cordons Peut-être que vous voulez déballer alors:

pickChord : Model -> Note -> Chord 
pickChord model note = 
    let 
     nextChord = List.head (List.filter (testChord note) model.possibleMajorChords) 
    in 

    case nextChord of     
     Nothing ->        
     //some error here if you want 

     Just cord ->        
     cord 
1

Parce que List.head vous ne donnera pas un élément dans le cas d'une liste vide, vous devez soit fournir une valeur par défaut

pickChord : Model -> Note -> Chord 
pickChord model note = 
    withDefault <chord> (List.head (List.filter (testChord note) model.possibleMajorChords)) 

Ou laisser la valeur par défaut Chord à l'appelant.

pickChord : Model -> Note -> Maybe Chord 
pickChord model note = 
    List.head (List.filter (testChord note) model.possibleMajorChords)