0
votes

Comment séquencer des conditions lors de l'utilisation de l'un ou l'autre

Alors je construisai cette application CLI Todos pour apprendre de HASKELLL et j'essaie de rationaliser la manipulation des erreurs (je pense qu'il y a trop de code à l'aide de mon approche actuelle).

et j'ai donc écrit cette fonction à mettre à jour une tâche à une position spécifique en appliquant une fonction sur celle-ci: xxx

Cela fonctionne bien, mais je pense que je manque quelque chose et il devrait y avoir un moyen d'écrire Ceci en utilisant des *> ou >> ou >> = , mais je ne peux pas sembler pouvoir trouver la combinaison. Je viens de commencer à saisir comment les chaîner ensemble ... :) Le raisonnement pour tenter d'y accomplir est que cette fonction est appelée dans une autre qui fait ses propres pré-validations et que le code est déjà désordonné.

J'ai essayé divers permutations dans les lignes du bloc suivant (C'est juste un exemple), mais dès le premier moment, j'ai senti que cette approche ne peut pas fonctionner car ce n'est pas le moyen de "jeter" de peut-être non plus. xxx > Mon intuition me dit qu'il devrait y avoir une fonction qui peut être chaînée comme ceci.

FYI: Type Error = Texte , j'utilise Protolutude et surchargeStrings

Le code est en place chez https://github.com/ssipos90/todos-hs Mais c'est un peu daté. J'ai commencé à travailler sur l'analyse du fichier "base de données" à l'aide de Megaparsec, mais je pense que la manipulation des erreurs est plus importante.


0 commentaires

3 Réponses :


4
votes

La définition de fuu code> que vous recherchez est: xxx pré>

voici pourquoi ... l'opérateur (*>) code > a type: p> xxx pré>

dans ce contexte, f code> est spécialisé dans d'une erreur code>, donc c'est réellement: p> xxx pré>

si vous souhaitez écrire fuu p "xxx" *> autre_action code>, le type du résultat sera le type de Autre_action Code> (nommément Erreur B code> pour certains B code>). Vous devez définir fuu code> de sorte que le fichier fuu p "xxx" code> a le type soit l'erreur a code> pour certains caractères A code >, où peu importe quel type a code> est: p> xxx pré>

Si vous vous trouvez dans une situation où vous devez fournir un ??? code> où la valeur et le type ne comptent pas, la valeur / type () code> est toujours un bon pari: p> xxx pré>

Notez qu'il est commun à écrire: p> xxx pré>

en utilisant lorsque code> à partir de contrôler.monad code>, au lieu de la peine Définir fuu code>. p>

En outre, vous pouvez trouver que votre fonction semble un peu plus naturelle lors de la réécriture de la notation: p>

import Control.Monad

updateTodoAt' :: Int -> (Todo -> Either Error Todo) 
     -> [Todo] -> Either Error [Todo]
updateTodoAt' position fn todos = do
  when (n < 0) $ Left "Must be a strict positive, bruh!"
  when (n > length todos) $ Left "Out of bounds?"
  todo <- fn (todos !! n)
  return $ take n todos ++ [todo] ++ drop (n+1) todos
  where n = position - 1


3 commentaires

Cool. J'ai essayé d'écrire fuu comme fuu :: bool -> erreur -> soit une erreur A mais il est erroné. Aussi, j'ai cherché hoogle pour bool -> e -> e A a . Jamais traversé mon esprit pour utiliser le "tuple vide". Merci beaucoup!


échec S n'est pas gauche s , cependant.


échouer est destiné à manipuler les défaillances de la correspondance des motifs; Il n'est pas destiné à signaler une erreur arbitraire.



0
votes

Il vous suffit d'utiliser fmap ici: xxx


1 commentaires

Le code fonctionne bien, j'essayais simplement de la réécrire sans utiliser de garde.at Ce point, j'ai beaucoup de fonctions d'assistance ou de déclarations de cas à cause de la façon dont j'ai écrit. J'essaie de comprendre comment chaîner et nier soit s.



0
votes

N'utilisez pas !! code>. Il n'y a vraiment que deux conditions d'erreur:

  1. n code> est négatif li>
  2. La liste d'entrée est vide (ce qui implique le non négatif n code> est trop grand) li> ol>

    Compte tenu d'un N code> non négatif et d'une liste non vide, vous appliquerez la fonction à la première liste de liste ou recueil. P>

    updateTodoAt n _ xs
        | n < 0 = Left "negative index"
        | null xs = Left "index too large"
    updateTodoAt 0 fn (x:xs) = (: xs) <$> (fn x)
    updateTodoAt n fn (x:xs) = (x :) <$> updateTodoAt (n-1) fn xs
    


0 commentaires