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: p> Cela fonctionne bien, mais je pense que je manque quelque chose et il devrait y avoir un moyen d'écrire Ceci en utilisant des 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. p> FYI: 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. P> p> *> code> ou
>> code> ou
>> = code>, 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é. P>
Type Error = Texte code>, j'utilise Protolutude et surchargeStrings P>
3 Réponses :
La définition de voici pourquoi ... l'opérateur dans ce contexte, si vous souhaitez écrire Si vous vous trouvez dans une situation où vous devez fournir un Notez qu'il est commun à écrire: p> en utilisant En outre, vous pouvez trouver que votre fonction semble un peu plus naturelle lors de la réécriture de la notation: p> fuu code> que vous recherchez est:
(*>) code > a type: p>
f code> est spécialisé dans
d'une erreur code>, donc c'est réellement: p>
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>
??? code> où la valeur et le type ne comptent pas, la valeur / type
() code> est toujours un bon pari: p>
lorsque code> à partir de
contrôler.monad code>, au lieu de la peine Définir
fuu code>. 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
Cool. J'ai essayé d'écrire fuu code> comme
fuu :: bool -> erreur -> soit une erreur A code> mais il est erroné. Aussi, j'ai cherché hoogle pour
bool -> e -> e A a code>. Jamais traversé mon esprit pour utiliser le "tuple vide". Merci beaucoup!
échec S code> n'est pas
gauche s code>, cependant.
échouer code> est destiné à manipuler les défaillances de la correspondance des motifs; Il n'est pas destiné à signaler une erreur arbitraire.
Il vous suffit d'utiliser fmap code> ici:
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 code> s.
N'utilisez pas Compte tenu d'un !! code>. Il n'y a vraiment que deux conditions d'erreur:
n code> est négatif li>
n code> est trop grand) li>
ol>
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