Роман Чепляка
FUNCTION toUnixTime(year, month, day)
INTEGER :: toUnixTime
INTEGER :: year
INTEGER :: month
INTEGER :: day
...
END FUNCTION
struct Date {
int year;
int month;
int day;
};
int toUnixTime(struct Date d);
newtype Year = Year Int
newtype Month = Month Int
newtype Day = Day Int
newtype Unix = Unix Int
data Date = Date Year Month Day
toUnixTime :: Date -> Unix
data Date = Date Year Month Day
deriving (Eq, Ord, Show)
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Year = Year Int
deriving ( Eq, Ord, Show,
Real, Integral, Num,
Serial, ToJSON, FromJSON )
{-# LANGUAGE TemplateHaskell #-}
data Date = Date Year Month Day
deriveJSON ''Date
deriveJSON :: Name -> Q [Dec]
deriveJSON name = do
{- ... -}
data Date = Date Year Month Day
type DateView = (Int, Int, Int)
toGeneric :: Date -> DateView
toGeneric (Date (Year y) (Month m) (Day d)) = (y, m, d)
fromGeneric :: DateView -> Date
fromGeneric (y, m, d) = (Date (Year y) (Month m) (Day d))
dateEq :: Date -> Date -> Date
dateEq d1 d2 =
toGeneric d1 == toGeneric d2
class Generic a where
toGeneric :: a -> View
fromGeneric :: View -> a
genericEq :: Generic a => a -> a -> a
genericEq x y =
toGeneric x == toGeneric y
class Generic a where
type Rep a
toGeneric :: a -> Rep a
fromGeneric :: Rep a -> a
genericEq :: (Generic a, Eq (Rep a)) => a -> a -> a
genericEq x y =
toGeneric x == toGeneric y
instance Generic Date where
type Rep Date = (Int, (Int, Int))
class Hashable a where hash :: a -> Int
instance Hashable Int where
hash n = n `mod` 13
instance Hashable (a,b) where
hash (a,b) = 7 * hash a + hash b
genericHash :: (Generic a, Hashable (Rep a)) => a -> Int
genericHash x = hash (toGeneric x)
instance Hashable (Either a b) where
hash (Left a) = hash (a, 1)
hash (Right b) = hash (b, 2)
Show/Read/JSON
data Maybe a = Nothing | Just a
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
data (:+:) f g p = L1 (f p) | R1 (g p)
data (:*:) f g p = f p :*: g p
data U1 p = U1
data V1 p
newtype Par1 p = Par1 p
newtype K1 i c p = K1 c
newtype (f :.: g) p = Comp1 { unComp1 :: f (g p) }
class Generic1 f where
type Rep1 f :: * -> *
from1 :: f a -> Rep1 f a
to1 :: Rep1 f a -> f a
data Maybe a = Nothing | Just a
instance Generic1 Maybe where
type Rep1 f = U1 :+: Par1
instance Functor U1 where
fmap _ U1 = U1
instance Functor Par1 where
fmap f (Par1 a) = Par1 (f a)
instance Functor (K1 i c) where
fmap _ (K1 a) = K1 a
instance (Functor f) => Functor (Rec1 f) where
fmap f (Rec1 a) = Rec1 (fmap f a)
instance (Functor f, Functor g) => Functor (f :+: g) where
fmap f (L1 a) = L1 (fmap f a)
fmap f (R1 a) = R1 (fmap f a)
instance (Functor f, Functor g) => Functor (f :*: g) where
fmap f (a :*: b) = fmap f a :*: fmap f b
instance (Functor f, Functor g) => Functor (f :.: g) where
fmap f (Comp1 x) = Comp1 (fmap (fmap f) x)
genericFmap :: Generic1 f => (a -> b) -> (f a -> f b)
genericFmap f = to1 . fmap f . from1
data Maybe a = Nothing | Just a
instance Generic (Maybe a) where
type Rep f = U1 :+: K1 R a
data M1 f p = M1 Info (f p)
data Info
= DatatypeName String
| ConstructorName String
| SelectorName String
data M1 f p = M1 (f p)
data M1 i c f p = M1 (f p)
data M1 i c f p = M1 (f p)
i
— один из:
data D
data C
data S
class Datatype c where
datatypeName :: t c f p -> String
moduleName :: t c f p -> String
isNewtype :: t c f p -> Bool
type Rep1 Maybe =
M1 D D1Maybe
(M1 C C1_0Maybe U1
:+:
M1 C C1_1Maybe (M1 S NoSelector Par1))
-- option 1
type Rep Date = Int :*: Int :*: Int
-- option 2
type Rep Date = Year :*: Month :*: Date