Haskell – 201 – sintassi e semantica

Continuo da qui, copio qui.

Si parte caricando il file literate.

Poi cominciano le difficoltà: la lezione è OK se sei presente fisicamente, con i compagni più smart e il prof. Io sono qui solo, vecchio e quindi meno aggiornato e condizionato da cattive abitudini (ultimamente bash oltre a Python) e alle volte (anzi molto spesso) non riesco a stare al passo con la classe.

Ma ce la metto tutta, per esempio:

Prelude> :l 04-syntax-semantics.lhs
[1 of 1] Compiling Main             ( 04-syntax-semantics.lhs, interpreted )
Ok, modules loaded: Main.
*Main> parseMirror "L.R"
(Layer Middle,"")
*Main> parseMirror "L.L"
*** Exception: 04-syntax-semantics.lhs:(155,5)-(156,42): Non-exhaustive patterns in case

*Main> parseMirror "LL.RR"
(Layer (Layer Middle),"")
*Main> parseMirror "LL.RR.LL"
(Layer (Layer Middle),".LL")

Poi arriva l’esercizio vero, BIN:

--bin.hs

{-# LANGUAGE GADTs #-}

import Data.Char

-- http://ozark.hendrix.edu/~yorgey/360/f16/modules/04-syntax-semantics.html

data Bin where
    Hash :: Bin
    Layer :: Bin -> Bin -> Bin
    deriving Show

prettyBin :: Bin -> String
prettyBin Hash = "#"
prettyBin (Layer x y) = "(" ++ prettyBin x ++ prettyBin y ++ ")"


parseBin :: String -> Maybe (Bin, String)
parseBin ('#' : rest) = Just (Hash, rest)
parseBin ('(' : rest) =
    case parseBin rest of
        Just (x, rest') -> case parseBin rest' of
            Just (y, ')' : rest'') -> Just (Layer x y, rest'')
            _ -> Nothing
        _ -> Nothing
parseBin _ = Nothing

interpBin :: Bin -> Integer
interpBin Hash = 1
interpBin (Layer l r) = interpBin l + 2 * (interpBin r)

evalBin :: String -> Maybe Integer
evalBin xs = do
    (bin, _) <- parseBin xs
    return $ interpBin bin

{-
   ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
 ::= '#'
        | 
        | '('   ')'
-}

data EBin where
    EHash :: EBin
    Digit :: Int -> EBin
    ELayer :: EBin -> EBin -> EBin
    deriving Show

prettyEBin :: EBin -> String
prettyEBin EHash = "#"
prettyEBin (Digit d) = show d
prettyEBin (ELayer x y) = "(" ++ prettyEBin x ++ prettyEBin y ++ ")"

parseEBin :: String -> Maybe (EBin, String)
parseEBin ('#' : rest) = Just (EHash, rest)
parseEBin ('(' : rest) =
    case parseEBin rest of
        Just (x, rest') -> case parseEBin rest' of
            Just (y, ')' : rest'') -> Just (ELayer x y, rest'')
            _ -> Nothing
        _ -> Nothing
parseEBin (c : rest) | isDigit c = Just (Digit $ read [c], rest)
                     | otherwise = Nothing
parseEBin _ = Nothing

desugar :: EBin -> Bin
desugar EHash = Hash
desugar (Digit d) = grow d where
    grow 0 = Hash
    grow n = let inner = grow (n-1) in Layer inner inner
desugar (ELayer l r) = Layer (desugar l) (desugar r)


evalEBin :: String -> Maybe Integer
evalEBin xs = do
    (ebin, _) <- parseEBin xs
    return $ interpBin $ desugar ebin
*Main> :l bin
[1 of 1] Compiling Main             ( bin.hs, interpreted )
Ok, modules loaded: Main.
*Main> evalEBin "(#2)"
Just 19
*Main> evalEBin "(#4) (#2)"
Just 163
*Main> evalEBin "((#4) (#2))"
Nothing
*Main> evalEBin "((#4)(#2))"
Just 201
*Main> evalEBin "0"
Just 1
*Main> evalEBin "1"
Just 3
*Main> evalEBin "2"
Just 9
*Main> evalEBin "#"
Just 1
*Main> evalEBin "##"
Just 1
*Main> evalEBin "(##)"
Just 3
*Main> evalEBin "((##) (##))"
Nothing
*Main> evalEBin "((##)(##))"
Just 9

Uhmmmmysteryousassay 😯

Hai copiato? Sì, qui.

Devo rivedere profondamente il modo con cui affronto il corso.

Posta un commento o usa questo indirizzo per il trackback.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: