Disons que j'ai le type de données suivant:
data MyType = Element1 (Maybe Int) | Element2 (Maybe Int) instance1 = Element1 (Just 1) instance2 = function(instance1)
Que puis-je utiliser à la place de function
avec pour que instance2 = Element1 (Just 2) ?
3 Réponses :
Si vous générez légèrement votre type, vous pouvez en faire un foncteur:
data MyTypeTags = Element1 | Element2 data MyType = MyType MyTypeTags (Maybe Int) change :: Int -> MyType -> MyType change new (MyType tag old) = MyType tag (new <$ old)
Ensuite, la fonction que vous recherchez est (, du
Functor
typeclass.
data MyType = Element1 (Maybe Int) | Element2 (Maybe Int) change :: Int -> MyType -> MyType change new (Element1 old) = Element1 (new <$ old) change new (Element2 old) = Element2 (new <$ old)
Si vous ne souhaitez pas utiliser l'extension DeriveFunctor
, l'instance est trivial à définir manuellement.
instance Functor MyType where fmap f (Element1 x) = Element1 (fmap f x) fmap f (Element2 x) = Element2 (fmap f x)
Une version spécialisée de ( pour un type monomorphe pourrait ressembler à
XXX
Ou, vous pouvez définir votre type en tant que produit, pour généraliser la fonction sur les constructeurs de données.
> i1 = Element1 (Just 1) > i1 Element1 (Just 1) > 2 <$ i1 Element1 (Just 2)
Merci. Cependant, si, par exemple, a
devait avoir le type Int
, y a-t-il un moyen de contourner ce problème?
Vous pouvez envisager d'utiliser la classe MonoFunctor
de la bibliothèque mono-traversible
. Sinon, je pense que vous auriez juste besoin d'écrire votre propre fonction change :: Int -> MyType -> MyType
, similaire à (<$)
, à la main.
Vous donnez trois équations:
function (Element1 (Just 1)) = Element1 (Just 2)
Utilisons ces équations pour résoudre la fonction
.
function (instance1) = instance2 function (Element1 (Just 1)) = instance2 function (Element1 (Just 1)) = Element1 (Just 2)
Cette dernière ligne:
instance1 = Element1 (Just 1) instance2 = function(instance1) instance2 = Element1 (Just 2)
est un très bon morceau de code Haskell qui définit une fonction nommée function
. Bien sûr, il ne dit pas quoi faire des choses qui sont en fait des Element2
, ou qui sont des Element1
contenant des Nothing
, ou qui sont des Element1
contenant des Just
s contenant des choses qui ne sont pas 1
! Mais cela répond aux spécifications données par les trois équations originales, et je pense que c'est une excellente démonstration du concept de «raisonnement équationnel» que Haskell partage avec les mathématiques.
Vous pouvez définir votre type de données en utilisant la syntaxe d'enregistrement:
data MyType = Element1 { x :: (Maybe Int) } | Element2 { x :: (Maybe Int)} instance1 = Element1 (Just 1) instance2 = instance1 { x = Just 2 }
Vous ne pouvez pas manipuler un objet. Toutes les valeurs sont immuables . Vous pouvez construire un nouvel objet, c'est-à-dire une copie modifiée de l'original.
Ce que vous voulez faire n'est cependant pas tout à fait clair. Qu'est-ce que c'est un
Element2 Nothing
? Ou unElement1 (Just 3)
?@WillemVanOnsem J'ai édité la question pour refléter l'immuabilité d'un objet et clarifier ma question.
Vous utilisez correspondance de modèles