Égal (=) Vs flèche vers la gauche (<-) symboles en haskell
Code de travail:
import System
main = do
[file1, file2] <- getArgs
--copy file contents
str <- readFile file1
writeFile file2 str
S'écraser code:
import System
main = do
[file1, file2] = getArgs
str = readFile file1
writeFile file2 str
Quand j'ai essayé, il a jeté une erreur comme:
un.hs:6:18: parse error sur l'entrée '='
Alors, combien est différent <-
de =
?
- Vous avez besoin de comprendre Monade de-la cabane à sucre pour avoir une réelle idée de la façon dont cela s'inscrit.
- c'est techniquement vrai, mais je pense qu'il devrait être possible de répondre à cette question, sans parler de la M-parole. Après tout, m***ds sont juste une façon de traiter avec les IO dans une langue pure. Haskell aurait encore une séparation entre le pur et l'impur code, même si elle n'a pas m****ds construit dans la langue, et ce problème (ou similaire), il existerait toujours.
- Alors qu'il est possible de répondre à cette question sans expliquer la Monade, je doute vraiment si cela peut aider les OP à saisir le concept. Cela étant dit, il ya beaucoup de bonnes réponses ici-bas.
Vous devez vous connecter pour publier un commentaire.
De comprendre la véritable différence, vous devez comprendre les monades, et la desugaring décrite par @rightfold dans leur réponse.
Pour le cas spécifique de l'IO monade, comme dans votre
getArgs
exemple, un brouillon mais utile intuition peut être effectué comme suit:x <- action
s'exécute le IOaction
, obtient son résultat, et le lie àx
let x = action
définitx
équivalent àaction
, mais ne pas exécuter quoi que ce soit. Plus tard, vous pouvez utilisery <- x
sensy <- action
.Programmeurs venant de langages qui permettent de fermetures, peuvent tirer de cette rude en parallèle avec Javascript:
Encore: cette comparaison porte sur IO, seulement. Pour les autres monades, vous avez besoin de vérifier ce
>>=
est réellement, et de réfléchir à la desugaring dedo
.est équivalent à:
est équivalent à
c'est à dire
let
/=
ne pas monadique lier alors que<-
n'.let x = y in f x
(qui vraiment est équivalent à la 2ème expression do) est "équivalent" àf y
est dangereux, principalement parce qu'il peut ne pas être évident pour le lecteur que "équivalent" signifie; les valeurs de ces deux expressions sont les mêmes, mais leur sémantique peut être différent.Le code ne se compile pas, parce que les types ne correspondent pas. Nous allons charger un GHCI session et de regarder les types de fonctions que vous utilisez
Donc
writeFile
veut unFilePath
et unString
. Vous voulez obtenir leString
dereadFile
- maisreadFile
retourneIO String
au lieu deString
.Haskell est un très raisonnée de la langue. Il a une distinction entre pur fonctions (ce qui donne les mêmes sorties à chaque fois qu'ils sont appelés avec les mêmes arguments) et impur code (qui peuvent donner des résultats différents, par exemple si la fonction dépend de certains saisie de l'utilisateur). Les fonctions qui traitent des entrées/sorties (IO) ont toujours un type de retour qui est marqué avec
IO
. Le type de système garantit que vous ne pouvez pas utiliser impurIO
code à l'intérieur de pures fonctions - par exemple, au lieu de retourner unString
la fonctionreadFile
retourne unIO String
.C'est là que le
<-
notation est important. Il vous permet d'obtenir à laString
à l'intérieur de laIO
et il assure que tout ce que vous faites avec cette chaîne, la fonction de la définition va être marquée par laIO
. Comparer les suivantes -ce qui n'est pas ce que nous voulons, à ce
qui est ce que nous voulons. Si jamais vous avez une fonction qui renvoie un
IO a
et vous souhaitez accéder à laa
, vous devez utiliser<-
d'affecter le résultat d'un nom. Si votre fonction ne retourne pasIO a
, ou si vous ne voulez pas d'obtenir à laa
à l'intérieur de laIO
vous pouvez simplement utiliser=
.<-
pour obtenir le résultat calculé force pour cela, à l'intérieur IOdo
bloc, pour être capable de faire cela. ainsi, l'application de la séparation de l'impur IO de code pur.Cela prend l'action "
readFile file1
" et les magasins l'action dansx
.Ce exécute l'action "
readFile file1
" et les magasins le résultat de l'action dansx
.Dans le premier exemple,
x
est un non I/O action de l'objet. Dans le deuxième exemple,x
est le contenu d'un fichier sur le disque.