J'essaie de traduire traverse
/sequenceA
en Javascript. Maintenant, le comportement suivant de la mise en œuvre Haskell me donne du mal:Le passage de type explicite n'est-il pas équivalent à l'inférence de type (en termes d'expressivité)?
traverse (\x -> x) Nothing -- yields Nothing
sequenceA Nothing -- yields Nothing
traverse (\x -> x) (Just [7]) -- yields [Just 7]
sequenceA (Just [7]) -- yields [Just 7]
En tant que débutant Haskell Je me demande pourquoi la première expression fonctionne à tous:
instance Traversable Maybe where
traverse _ Nothing = pure Nothing
traverse f (Just x) = Just <$> f x
pure Nothing
ne devraient pas travailler dans ce cas, étant donné que il n'y a pas de contexte applicatif minimal dans lequel la valeur pourrait être mise. Il semble que le compilateur vérifie paresseusement le type de cette expression et que le mappage de la fonction id sur Nothing
est un noop, il "ignore" simplement l'erreur de type, donc parler.
Voici ma traduction Javascript:
(S'il vous plaît noter que depuis le système prototype de Javascirpt est insuffisant pour deux classes de type et il n'y a pas de type vérification stricte de toute façon, je travaille avec le codage de l'Eglise et passe des contraintes de type à fonctions explicitement.)
// minimal type system realized with `Symbol`s
const $tag = Symbol.for("ftor/tag");
const $Option = Symbol.for("ftor/Option");
const Option = {};
// value constructors (Church encoded)
const Some = x => {
const Some = r => {
const Some = f => f(x);
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
const None = r => {
const None = f => r;
return None[$tag] = "None", None[$Option] = true, None;
};
None[$tag] = "None";
None[$Option] = true;
// Traversable
// of/map are explicit arguments of traverse to imitate type inference
// tx[$Option] is just duck typing to enforce the Option type
// of == pure in Javascript
Option.traverse = (of, map) => ft => tx =>
tx[$Option] && tx(of(None)) (x => map(Some) (ft(x)));
// (partial) Array instance of Applicative
const map = f => xs => xs.map(f);
const of = x => [x];
// helpers
const I = x => x;
// applying
Option.traverse(of, map) (I) (None) // ~ [None]
Option.traverse(of, map) (I) (Some([7])) // ~ [Some(7)]
de toute évidence, cette traduction diffère de la mise en œuvre Haskell, parce que je reçois un [None]
où je devrais obtenir un None
. Honnêtement, ce comportement correspond précisément à mon intuition, mais je suppose que l'intuition n'est pas très utile dans la programmation fonctionnelle. Maintenant, ma question est
- ai-je simplement fait une erreur de débutant?
- ou est le type explicite passant pas équivalent à l'inférence de type (en termes d'expressivité)?
L'erreur recrue c'est! – ftor