Personal tools

Legile monadei

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
 
Line 1: Line 1:
To do: Translate this:
+
Toate instantele clasei [[Monad]] trebuie sa se conformeze axiomelor de mai jos:(dati click pe [[Monad]] pentru explicatii in engleza despre clasa [Monad])
 
All instances of the [[Monad]] class should obey:
 
   
 
<haskell>
 
<haskell>
Line 7: Line 7:
 
</haskell>
 
</haskell>
   
== What is the practical meaning of the monad laws? ==
+
== Ce semnifica aceste reguli pentru programatorul interesat de aspectele practice ? ==
   
Let us re-write the laws in do-notation:
+
Daca scriem aceste reguli in do-notatie obtinem egalitatile:
   
 
<haskell>
 
<haskell>
Line 26: Line 26:
   
 
do { x <- m
 
do { x <- m
using 3.14 ; y <- f x
+
care conform 3.14 (?) ; y <- f x
 
== ; g y
 
== ; g y
 
}
 
}
 
</haskell>
 
</haskell>
   
In this notation the laws appear as plain common sense.
+
Cu aceasta notatie semnificatia regulilor este clara.
  +
  +
== Dar de ce trebuie monadele sa urmeze aceste reguli ? ==
   
== But why should monads obey these laws? ==
+
Atunci cand scriem un program in forma din stanga ne asteptam ca el sa
  +
faca exact acelasi lucru ca si forma sa din dreapta. Iar in practica,
  +
tot modificand un program se poate ajunge la forme ca cea din stanga care
  +
vor trebui sa se comporte asa cum ne asteptam.
   
When we see a program written in a form on the LHS, we expect it to do
+
Primul exemplu: incepatorii au tendinta sa scrie:
the same thing as the corresponding RHS; and vice versa. And in
 
practice, people do write like the lengthier LHS once in a while.
 
First example: beginners tend to write
 
   
 
<haskell>
 
<haskell>
Line 44: Line 44:
 
</haskell>
 
</haskell>
   
and it would really throw off both beginners and veterans if that did
+
iar un asemenea cod i-ar innebuni si pe incepatori si pe veterani daca
not act like (by law #2)
+
nu s-ar comporta (conform legii nr. 2) ca
   
 
<haskell>
 
<haskell>
Line 52: Line 52:
 
}
 
}
 
</haskell>
 
</haskell>
  +
Acesta ar fi doar un motiv necesar ca monadele sa verifice legea/axioma
  +
nr. 2.
   
Second example: Next, you go ahead to use skip_and_get:
+
Al doilea exemplu: Sa continuam cu folosirea lui skip_and_get:
   
 
<haskell>
 
<haskell>
Line 61: Line 63:
 
</haskell>
 
</haskell>
   
The most popular way of comprehending this program is by inlining
+
Cel mai usor mod de a ne imagina exact efectul acestui apel este sa
(whether the compiler does or not is an orthogonal issue):
+
il scriem prin substitutie. Skip_and_get se inlocuieste cu codul lui.
  +
(daca un compilator sau interpretor procedeaza exact asa este o cu
  +
totul alta discutie):
   
 
<haskell>
 
<haskell>
Line 72: Line 74:
 
</haskell>
 
</haskell>
   
and applying law #3 so you can pretend it is
+
si numai aplicand axioma/legea, nr.3, putem
  +
pretinde ca este echivalent cu:
   
 
<haskell>
 
<haskell>
Line 81: Line 83:
 
</haskell>
 
</haskell>
   
Law #3 is amazingly pervasive: you have always assumed it, and you
+
Legea/axioma nr. 3 este in ciuda aparentelor uluitor de penetranta:
have never noticed it.
+
cu siguranta ati presupus-o adevarata si ati folosit-o dar niciodata
  +
nu v-ati pus problema existentei sale in forma axiomatica de mai sus.
   
Whether compilers exploit the laws or not, you still want the laws for
+
Indiferent daca compilatorul foloseste sau nu (pentru optimizari)
your own sake, just so you can avoid pulling your hair for
+
aceste legi cu siguranta veti dori sa fiti sub "protectia lor"
counter-intuitive program behaviour that brittlely depends on how many
+
pentru binele (adica bunul comportament al) programelor dumneavoastra.
redundant "return"s you insert or how you nest your do-blocks.
+
Doar in acest mod puteti sa va feriti de a va smulge parul din cap
  +
din cauza unor comportamente anti-intuitive. Acestea s-ar manifesta
  +
dupa niste modificari altminteri minore cum ar fi introducerea unor
  +
"return"-uri redundante sau schimbarea numarului de do-uri imbricate.
   
  +
Explicatii conexe in limba engleza:
 
[[Category:Standard_classes]]
 
[[Category:Standard_classes]]
 
[[Category:Monad]]
 
[[Category:Monad]]

Revision as of 21:40, 29 January 2007

Toate instantele clasei Monad trebuie sa se conformeze axiomelor de mai jos:(dati click pe Monad pentru explicatii in engleza despre clasa [Monad])

1. return a >>= f  =  f a
2. m >>= return  =  m
3. (m >>= f) >>= g = m >>= (\x -> f x >>= g)

1 Ce semnifica aceste reguli pentru programatorul interesat de aspectele practice ?

Daca scriem aceste reguli in do-notatie obtinem egalitatile:

1. do { x' <- return x            do { f x
      ; f x'               ==        }
      }
 
2. do { x <- m             ==     do { m
      ; return x }                   }
 
3. do { y <- do { x <- m          do { x <- m
                ; f x                ; do { y <- f x
                }          ==             ; g y
      ; g y                               }
      }                              }
 
                                  do { x <- m
         care conform  3.14  (?)     ; y <- f x
                           ==        ; g y
                                     }

Cu aceasta notatie semnificatia regulilor este clara.

2 Dar de ce trebuie monadele sa urmeze aceste reguli ?

Atunci cand scriem un program in forma din stanga ne asteptam ca el sa faca exact acelasi lucru ca si forma sa din dreapta. Iar in practica, tot modificand un program se poate ajunge la forme ca cea din stanga care vor trebui sa se comporte asa cum ne asteptam.

Primul exemplu: incepatorii au tendinta sa scrie:

skip_and_get = do { unused <- getLine
                  ; line <- getLine
                  ; return line
                  }

iar un asemenea cod i-ar innebuni si pe incepatori si pe veterani daca nu s-ar comporta (conform legii nr. 2) ca

skip_and_get = do { unused <- getLine
                  ; getLine
                  }

Acesta ar fi doar un motiv necesar ca monadele sa verifice legea/axioma nr. 2.

Al doilea exemplu: Sa continuam cu folosirea lui skip_and_get:

main = do { answer <- skip_and_get
          ; putStrLn answer
          }

Cel mai usor mod de a ne imagina exact efectul acestui apel este sa il scriem prin substitutie. Skip_and_get se inlocuieste cu codul lui. (daca un compilator sau interpretor procedeaza exact asa este o cu totul alta discutie):

main = do { answer <- do { unused <- getLine
                         ; getLine
                         }
          ; putStrLn answer
          }

si numai aplicand axioma/legea, nr.3, putem pretinde ca este echivalent cu:

main = do { unused <- getLine
          ; answer <- getLine
          ; putStrLn answer
          }

Legea/axioma nr. 3 este in ciuda aparentelor uluitor de penetranta: cu siguranta ati presupus-o adevarata si ati folosit-o dar niciodata nu v-ati pus problema existentei sale in forma axiomatica de mai sus.

Indiferent daca compilatorul foloseste sau nu (pentru optimizari) aceste legi cu siguranta veti dori sa fiti sub "protectia lor" pentru binele (adica bunul comportament al) programelor dumneavoastra. Doar in acest mod puteti sa va feriti de a va smulge parul din cap din cauza unor comportamente anti-intuitive. Acestea s-ar manifesta dupa niste modificari altminteri minore cum ar fi introducerea unor "return"-uri redundante sau schimbarea numarului de do-uri imbricate.

Explicatii conexe in limba engleza: