2016.12.30 17:12
haskellowy koan

Wymyśliłem wczoraj taki haskellowy koan:
Oto prosta biblioteka do generowania zapytań eskuelowych - sprytna, bo kiedy budujemy nią wyrażenia, to pilnuje typów (na przykład żebyśmy pola tekstowego nie mnożyli przez liczbę):
data Table = Table String deriving Show

data Expression a = Expression String deriving Show

integerField :: String -> Expression Integer
integerField name = Expression name

integerLiteral :: Integer -> Expression Integer
integerLiteral value = Expression (show value)

(|+|) :: Expression Integer -> Expression Integer -> Expression Integer
(|-|) :: Expression Integer -> Expression Integer -> Expression Integer
(|*|) :: Expression Integer -> Expression Integer -> Expression Integer
(|/|) :: Expression Integer -> Expression Integer -> Expression Integer
(|+|) (Expression a) (Expression b) = Expression ("(" ++ a ++ " + " ++ b ++ ")")
(|-|) (Expression a) (Expression b) = Expression ("(" ++ a ++ " - " ++ b ++ ")")
(|*|) (Expression a) (Expression b) = Expression ("(" ++ a ++ " * " ++ b ++ ")")
(|/|) (Expression a) (Expression b) = Expression ("(" ++ a ++ " / " ++ b ++ ")")

stringField :: String -> Expression String
stringField name = Expression name

stringLiteral :: String -> Expression String
stringLiteral value = Expression (""" ++ value ++ """)

(|&|) :: Expression String -> Expression String -> Expression String
(|&|) (Expression a) (Expression b) = Expression (a ++ " & " ++ b)

data AnyExpression = IntegerExpression (Expression Integer) | StringExpression (Expression String)

expressionsToSql :: [AnyExpression] -> String
expressionsToSql [] = ""
expressionsToSql [IntegerExpression (Expression a)] = a
expressionsToSql [StringExpression (Expression a)] = a
expressionsToSql ((IntegerExpression (Expression a)):xs) = a ++ ", " ++ (expressionsToSql xs)
expressionsToSql ((StringExpression (Expression a)):xs) = a ++ ", " ++ (expressionsToSql xs)

toSql :: Table -> [AnyExpression] -> String
toSql (Table name) expressions = "select " ++ (expressionsToSql expressions) ++ " from " ++ name
Korzysta się z niej na przykład tak:
waga = integerField "waga"
wzrost = integerField "wzrost"
imie = stringField "imie"
nazwisko = stringField "nazwisko"
int_1337 = integerLiteral 1337
str_tralala = stringLiteral "tralala"
sql = toSql (Table "osoby") [IntegerExpression (waga |*| wzrost), IntegerExpression (waga |+| int_1337 |-| wzrost), StringExpression (imie |&| str_tralala |&| nazwisko)]
A teraz spróbuj napisać funkcję, która z rzeczy typu Expression Integer wyciąga ten integer. To znaczy napisz funkcję, która jest typu Expression Integer -> Integer.

Wymyśliłem to rozmyślając o haskellowym IO.

komentarze:

ksywa:

tu wpisz cyfrę cztery: (tu wpisz cyfrę cztery: (to takie zabezpieczenie antyspamowe))

komentarze wulgarne albo co mi się nie spodobają będę kasował


powrót na stronę główną

RSS