PLNC 2010 Site pédagogique de l'unité d'enseignement INF355 (Paradigmes et Langages Non Classiques) de Télécom ParisTech.
|
Haskell : notes de cours 1 (23 juin 2010)
 24 juin 2010 à 23 h 14 Samuel Tardieu dans Corrigé
module Cours1 where
-- Importation explicite du prélude en excluant certaines constructions :
-- - Maybe et tous ses constructeurs
-- - repeat
import Prelude hiding (Maybe(..), repeat)
-- Équivalence entre opérateurs et fonctions. Par exemple, (+) est la
-- fonction correspondant à l'addition et `f` ci-dessous est la version
-- opérateur de la fonction f.
x `f` y = x*2 + y*3
g x y = x*2 + y*3
x +!+ y = x*2 + y*3
-- Liste infinie de factorielle.
facts :: [Integer]
facts = 1 : (zipWith (*) [1..] facts)
-- Application partielle de !! qui permet de récupérer le n-ième
-- élément d'une liste.
fact :: Int -> Integer
fact = (facts !!)
-- Définition de la suite de Fibonacci.
fibos :: [Integer]
fibos = 1 : 1 : (zipWith (+) fibos (tail fibos))
-- Fonction constante qui, en application partielle, retourne toujours
-- la même chose lorsqu'elle est finalement appliquée.
c :: a -> b -> a
c x _ = x
-- Fonction qui fait la même chose avec son deuxième argument. J'y ajoute
-- une seconde définition s' qui utilise la fonction identité.
s :: a -> b -> b
s a b = c b a
s' :: a -> b -> b
s' _ = id
-- Équivalent de la fonction prédéfinie flip qui inverse l'ordre des
-- arguments d'une fonction en prenant deux.
fl :: (a -> b -> c) -> b -> a -> c
fl f x y = f y x
-- Lambda.
add = \ x y -> x+y
-- Nouveau type de données, affichable.
data B = T | F deriving (Show)
-- Ce type peut être utilisé pour des comparaisons en fournissant ==.
instance Eq B where
T == T = True
F == F = True
_ == _ = False
-- Type option similaire à ce qu'on avait fait en Factor.
data Maybe a = Just a | Nothing
deriving (Show)
fromJust :: Maybe a -> a
fromJust (Just x) = x
fromJust Nothing = error "empty Maybe"
app :: Maybe a -> (a -> Maybe b) -> Maybe b
app (Just x) f = f x
app Nothing _ = Nothing
-- Maybe est également un Monad si on fournit les bonnes fonctions.
instance Monad Maybe where
return = Just
fail _ = Nothing
(Just x) >>= f = f x
Nothing >>= _ = Nothing
-- Incrémentation de n'importe quel type de Monad si on utilise minc
-- avec la fonction bind (>>=).
minc :: (Monad m, Num a) => a -> m a
minc = return.(1+)
-- Utilisation de do.
mcomplex :: (Monad m, Num a) => m a -> m a
mcomplex x = do
v <- x
return $ (v+1)*2
-- En appliquant cette fonction à deux listes, on obtient le produit
-- cartésien. Si on l'applique à deux Maybe, on obtient un Maybe.
mpair :: Monad m => m a -> m b -> m (a,b)
mpair x y = do
xx <- x
yy <- y
return $ (xx,yy)
-- Utilisation d'une fonction normale à l'intérieur d'un monad en la
-- liftant. Ici, nous avons un exemple avec deux paramètres et avec
-- un seul.
liftm2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c
liftm2 f x y = do
xx <- x
yy <- y
return $ xx `f` yy
liftm :: Monad m => (a -> b) -> m a -> m b
liftm f = (>>= return.f)
-- Traduction d'un do en applications successives de >>= et >>.
toto = do
x <- [1,2,3]
return 3
return (x*2)
--[1,2,3] >>= (\x ->
-- return 3 >> (return (x*2)))
-- Utilisation du monad IO.
helloworld :: IO ()
helloworld = do
putStrLn "Hello"
putStrLn "World"
-- Répétition deux fois d'une chaîne saisie par l'utilisateur.
repeat :: IO ()
repeat = do
s <- getLine
putStrLn s
putStrLn s
-- Exemple de structure avec création de fonction automatique
-- permettant d'extraire les données.
data Person = Person { first :: String,
last :: String }
deriving (Show)
-- State monad. On veut garder un état implicite tout en manipulant
-- le contenu du monad avec les fonctions monadiques traditionnelles.
data SM s a = SM {runSM :: s -> (s,a)}
-- Bien entendu, le state monad est un monad.
instance Monad (SM s) where
return a = SM $ \s -> (s,a)
(SM x) >>= f = SM $ \ s ->
let (s', r) = x s
(s'', r') = runSM (f r) s'
in (s'', r')
-- Récupération du contenu de l'état en le liftant dans le monad.
get :: SM s s
get = SM $ \s -> (s,s)
-- Remplacement de l'état en ignorant l'état initial.
put :: s -> SM s ()
put s = SM $ \_ -> (s, ())
-- Modification de l'état. C'est équivalent à
-- change f = do
-- v <- get
-- put $ f v
-- mais l'écriture avec >>= est plis simple et plus lisible.
change :: (s -> s) -> SM s ()
change f = get >>= (put.f)
-- Exemple d'une fonction factorielle qui ajoute à un état
-- numérique le nombre de multiplications effectuées.
fact' :: (Num t, Ord t) => t -> SM Int t
fact' n = if n < 3
then return n
else do
temp <- fact' $ n-1
change (+1)
return $ n * temp
-- Extraction de l'état.
state :: SM s a -> s -> s
state m i = fst $ runSM m i
-- Extraction du contenu.
content :: SM s a -> s -> a
content m i = snd $ runSM m i
-- Illustration de let, where et de la différence de scoping entre
-- les deux.
ff x = let y = x+1
in y * 2
gg x = y * 2
where y = x+1
hh x | x >= 3 = x * temp
| otherwise = seq temp x
where temp = hh (x-1)
Comments are closed.
|
|
Commentaires récents