2017-09-25 4 views
2

J'ai un type de données algébrique comme:modèle Haskell correspondant à un résultat de la fonction

data Toll = Vok Int Bool | Bok Int | Cokd String Char 

et une autre fonction

getVal :: Int -> Toll 
getVal 1 = Cokd "hello" 'c' 
getVal _ = Bok 12 

Je veux appeler getVal dans une fonction et extraire les arguments de Cokd (si la réponse était de type Cokd) (peut-être en utilisant une correspondance de modèle).

que je peux faire comme:

hello :: Int -> Bool 
hello x = if st == "hell" then True else False 
where (Cokd st ch) = getVal x 

Je ne peux pas utiliser monades.

Comment faire?

+1

Voulez-vous que le modèle corresponde au résultat de 'getVal'? Quelque chose comme 'case getVal x de {Cokd str ch -> ...}'? – ZhekaKozlov

+0

puis-je faire comme dans le post de montage ci-dessus @ZhekaKozlov – Hok

Répondre

5

Vous pouvez utiliser case pour motif correspondre le résultat de getVal:

data Toll = Vok Int Bool | Bok Int | Cokd String Char 

getVal :: Int -> Toll 
getVal 1 = Cokd "hello" 'c' 
getVal _ = Bok 12 

hello :: Int -> Bool 
hello x = 
    case getVal x of 
    Cokd st ch -> 
     st == "hell" 
    _ -> False 

Ou créer une fonction distincte et modèle correspond l'argument:

hello :: Int -> Bool 
hello = 
    helloToll . getVal 
    where 
    helloToll (Cokd st ch) = st == "hell" 
    helloToll _ = False 

L'exemple, que vous a fourni dans la question compile (avec quelques modifications), mais il jettera une exception d'exécution lorsque vous essayez d'appeler hello avec 2 (ou toute autre valeur différente de 1, auquel cas getValue renvoie Bok 12, donc (Cokd st ch) = getVal x ne correspond pas à un modèle).

+0

la façon dont je montre dans le post original semble compiler, ça va fonctionner? @ igor- – Hok

+0

cela fonctionnera tant que vous fournissez '1' à' bonjour'. les autres valeurs échoueront. (mis à jour ma réponse) –

3

Votre code semble tout à fait correct, juste une correction: le motif if <expr> then True else False peut être remplacé par <expr>.

hello :: Int -> Bool 
hello x = st == "hell" where (Cokd st ch) = getVal x 

Cependant, ce code échouera pour les valeurs autres que 1 en raison de correspondance de motif non exhaustif. Vous devez couvrir tous les cas:

hello :: Int -> Bool 
hello x = case getVal x of 
    Cokd st ch -> st == "hell" 
    _ -> False