Podejście obiektowe i funkcyjne

1

Cześć szanownemu zgromadzeniu ludowemu
Znalazłem ciekawy artykuł-analizę na temat problemu ewaluacji wyrażeń arytmetycznych w językach C# i F#. Który język lepiej spełni swoją funkcję? Odpowiedź tutaj: http://www.neowin.net/forum/index.php?automodule=blog&blogid=460&showentry=3947
Taka ciekawostka do poczytania przy kawie. Enjoy :)

1

Dla porównania, podejście funkcyjne w Scali: Interpreter with continuations using monads

1

@Wibowit - Ty ze Scalą klasycznie, to ja może przedstawię wersję w Haskellu :P

data Exp = Op Exp (Int -> Int -> Int) Exp 
         | Literal Int

eval (Op a f b) = f (eval a) (eval b)
eval (Literal a) = a

4 linijki (coś pominąłem z funkcjonalności? W każdym razie poniższe działa).

Działa:

*Main> eval (Op 
    (Op (Literal 2) (+) (Literal 3)) 
    (*)
    (Op (Literal 4) (+) (Literal 5)))
45

Ale tak właściwie... W Haskellu da się lepiej - num jest jedną z typeclass (taki interfejs w Haskellu) więc można go spokojnie implementować:

data Func = Mul | Add | Sub deriving (Show, Eq)
data Num a => Exp a = Op (Exp a) Func (Exp a) | Lit a deriving (Show, Eq)

getFunc Add = (+)
getFunc Mul = (*)
getFunc Sub = (-)

instance (Num a) => Num (Exp a) where
    a + b = Op a Add b
    a - b = Op a Sub b
    a * b = Op a Mul b
    abs = undefined -- nie chce mi się
    signum = undefined -- nie chce mi się
    fromInteger = Lit . fromInteger

eval (Lit a) = a
eval (Op l f r) = (getFunc f) (eval l) (eval r)

Wygląda to o wiele ładniej:

*Main> (2 + 3) * (4 + 5) :: Exp Int
Op (Op (Lit 2) Add (Lit 3)) Mul (Op (Lit 4) Add (Lit 5))
*Main> eval ((2 + 3) * (4 + 5) :: Exp Int)
45
*Main> eval ((2 + 3) * (4 + 5))
45

Co to znaczy - że w tej chwili to, co wydaje się być zwykłym ciągiem operacji (np. 2 + 3) może zostać, w zależności od kontekstu automatycznie zmienione na naszą własną wewnętrzną strukturę i dowolnie modyfikowane...

IMO ciekawe jak w różnych dziwnych językach można implementować to samo zadanie. ;)

0

Haskell miażdży cyce jeśli chodzi o inferencję typów. Szkoda, że w Scali nie ma jej tak silnej. Jest w ogóle jakiś inny język z tak silną inferencją jak w Haskellu?

1 użytkowników online, w tym zalogowanych: 0, gości: 1