ç¹ç´ã·ãªã¢ã©ã¤ãºã©ã¤ãã©ãªãwinery 1.0解ç¦
ãããã9ã¶æâ¦wineryã®ãã¼ã¸ã§ã³1.0ãã¤ãã«ãªãªã¼ã¹ããã
ååã¾ã§ã®ãããã
ãã¼ã¿ã®ä¿åãéä¿¡ã«ç´ååã¯ä¸å¯æ¬ ã®æ¦å¿µã§ããã binaryãªã©ã®ç´ååã©ã¤ãã©ãªã¯ãã¬ã³ã¼ãã®ãã£ã¼ã«ãåãªã©ã®æ å ±ãæ¬ ãã¦ãããæ§é ãå¤ããã¨äºææ§ãæããããã¨ãã§ããªãã ä¸æ¹ãJSONãCBORãªã©ã®ãã©ã¼ãããã§æç´ã«ãã£ã¼ã«ãåãªã©ãæ®ãã¨æ¥µãã¦åé·ã«ãªããæéã»ç©ºéå¹çãæªãã ã³ã¼ãçæãåæã®Protobufãªã©ã¯Haskellã®æ¢åã®ãã¼ã¿æ§é ã¨ã®ç¸æ§ããããªãã ãããªç¾ç¶ã«æ®´ãè¾¼ã¿ããããã®ãwineryã ãå¤ããã¹ãã¼ããã¨ããã¼ã¿ãã«åå²ãã¦ä¿åãããã¨ã«ãã£ã¦ãåé·æ§ãé¿ãã¤ã¤ãã¡ã¿ãã¼ã¿ãä¿æããããã¨ãã§ãããwineryã¯æå¼·ã®ã©ã¤ãã©ãªã¨ãªããããâ¦ï¼
ç¹å¾´ã¨ç¹é·
JSON, MessagePack, CBORãªã©ãå¤ãã®ãã©ã¼ãããã§ã¯å¤ã«ãã£ã¼ã«ãåãªã©ã®æ å ±ãä»å±ãããã
[{"id": 0, "name": "Alice"}, {"id": 1, "name": "Bob"}]
wineryãéãã®ã¯ããããã¡ã¿ãã¼ã¿ããã¼ã¿æ¬ä½ããåé¢ããä¸ç®æã«ã¾ã¨ãã¦ä¿åãããã¨ã«ãããããã«ãããåé·æ§ã¯ãªããªãããããè¦ç´ ãwell-typedã§ãããã¨ãä¿è¨¼ããã
0402 0402 0269 6410 046e 616d 6514 [{ id :: Integer, name :: Text }] 0200 0541 6c69 6365 0103 426f 62 [(0, "Alice"), (1, "Bob")]
ã¡ã¿ãã¼ã¿ã®ãããã§ãã·ãªã¢ã©ã¤ã¶ã«äºææ§ãæããããã¨ãå¯è½ã¨ãªãããã¡ãããç®çã«å¿ãã¦ã¡ã¿ãã¼ã¿ãçããbinaryãcerealã¨åãããã«ä½¿ããã¨ãã§ããã æ´æ°ã®ã¨ã³ã³ã¼ãã«ã¯VLQãæ¡ç¨ãã¦ãããããbinaryãcerealãããçããªããããã
使ãæ¹
ã¾ãSerialise
ã®ã¤ã³ã¹ã¿ã³ã¹ãå®ç¾©ãããDerivingViaã使ã£ã¦ç°¡åã«ã¤ã³ã¹ã¿ã³ã¹ãå°åºã§ããããã®å°åºæ©æ§ã¯å帰çãªãã¼ã¿åã«ã対å¿ãã¦ããã
{-# LANGUAGE DerivingVia, DeriveGeneric, OverloadedStrings, ApplicativeDo #-} import Control.Applicative import Data.Winery import Data.Text (Text) import qualified Data.Text as T import GHC.Generics (Generic) data User = User { first_name :: !Text , last_name :: !Text , email :: !Text } deriving (Show, Generic) deriving Serialise via WineryRecord User
WineryRecord
ã¯ã©ã®ãããªã¤ã³ã¹ã¿ã³ã¹ã«ãããé¸ã¶ããã®ã©ããã¼ã ãç®çã«å¿ãã¦WineryProduct
(ãã£ã¼ã«ãåãªã), WineryVariant
(ã³ã³ã¹ãã©ã¯ã¿åãã)ã¨ä½¿ãåãããã
ãã¨ã¯serialise :: Serialise a => a -> ByteString
ã¨deserialise :: Serialise a => ByteString -> Either WineryException a
ã§èªç±ã«ã·ãªã¢ã©ã¤ãºã»ãã·ãªã¢ã©ã¤ãºãã§ããã
> serialise (User "Fumiaki" "Kinoshita" "[email protected]") "\EOT\EOT\ETX\nfirst_name\NAK\tlast_name\NAK\ENQemail\NAK\aFumiaki\tKinoshita\DC3[email protected]" > deserialise @User "\EOT\EOT\ETX\nfirst_name\NAK\tlast_name\NAK\ENQemail\NAK\aFumiaki\tKinoshita\DC3[email protected]" Right (User {first_name = "Fumiaki", last_name = "Kinoshita", email = "[email protected]"})
äºææ§
ã¬ã³ã¼ãã«ãã£ã¼ã«ãã追å ããã¨ãããããªã¢ã³ãããã³ã³ã¹ãã©ã¯ã¿ãåé¤ããã¨ããªã©ã«å¤ããã¼ã¿ã¨ã®äºææ§ã失ãããããããªå ´åã®ããã®å¦çãã³ã³ãã¼ã¶ãã«ã«è¨è¿°ã§ããä»çµã¿ãwineryã«ã¯åãã£ã¦ããã
Userã«Roleã¨ãããã£ã¼ã«ãã追å ãããå ´åãèãããã
data Role = Admin | Moderator | Member deriving (Show, Generic) deriving Serialise via WineryVariant Role data User = User { first_name :: !Text , last_name :: !Text , email :: !Text , role :: !Role } deriving (Show, Generic)
ãã¼ã¿ã«roleãæ¬ ãã¦ããå ´åã®æ¯ãèãããApplicativeDoè¨æ³ãç¨ãã¦ã«ã¹ã¿ãã¤ãºãã§ããããªãã¨ã¡ã¼ã«ã¢ãã¬ã¹ãexample.com
ã§çµãã£ã¦ããã°èªåã§ææ ¼ããã¨ãã£ãè¸å½ãå¯è½ã ã
instance Serialise User where bundleSerialise = bundleRecord $ const $ buildExtractor $ do f <- extractField "first_name" l <- extractField "last_name" e <- extractField "email" r <- const <$> extractField "role" <|> pure (\x -> if T.isSuffixOf "example.com" x then Moderator else Member) return $ User f l e (r e)
RoleããModeratorãåé¤ããå ´åãç°¡åã«å¯¾å¿ã§ããã
instance Serialise Role where bundleSerialise = bundleVia WineryVariant extractor = buildVariantExtractor $ HM.fromList [ ("Admin", pure Rice) , ("Moderator", pure Member) , ("Member", pure Member) ]
ããã©ã¼ãã³ã¹
ã©ããªã«ä¾¿å©ã§ãé
ãã¦ã¯ä»æ¹ããªããåºã使ããã¦ããbinary
, cereal
, aeson
, serialise
ã¨æ¯è¼ããããã®ãã¤ã¹ãã£ã³ã°ã»ã»ãã·ã§ã³ãè¡ã£ãã
課é¡ã¨ãªãã®ã¯ä»¥ä¸ã®ãã¼ã¿åã ãããããã®æ¹æ³ã§ã¤ã³ã¹ã¿ã³ã¹ãå°åºãã1000è¦ç´ ã®ãªã¹ãã®ã·ãªã¢ã©ã¤ãºã»ãã·ãªã¢ã©ã¤ãºãããã
data Gender = Male | Female deriving (Show, Generic) data TestRec = TestRec { id_ :: !Int , first_name :: !Text , last_name :: !Text , email :: !Text , gender :: !Gender , num :: !Int , latitude :: !Double , longitude :: !Double } deriving (Show, Generic) {- 1,Shane,Plett,[email protected],Male,-222,53.3928271,18.3836801 2,Mata,Snead,[email protected],Male,-816,51.5141668,-0.1331854 3,Levon,Sammes,[email protected],Male,485,51.6561,35.9314 ... -}
çµæã¯ä»¥ä¸ã®éãã ãwineryããã³ããã§éãã ãã§ãªããçæããããã¤ãåãæãçãã
encode 1 | encode 1000 | decode | length | |
---|---|---|---|---|
winery | 0.28 μs | 0.26 ms | 0.81 ms | 58662 |
cereal | 0.82 μs | 0.78 ms | 0.90 ms | 91709 |
binary | 1.7 μs | 1.7 ms | 2.0 ms | 125709 |
serialise | 0.61 μs | 0.50 ms | 1.4 ms | 65437 |
aeson | 9.9 μs | 9.7 ms | 17 ms | 160558 |
ç·è©
äºææ§ã¨æ¡å¼µæ§ããããããã¼ã¿åã«å¯¾å¿ã§ããæè»ãªå°åºã¡ã«ããºã ãããã¦åè¶ããããã©ã¼ãã³ã¹ã¨ç°¡æ½ãªè¡¨ç¾ãæä¾ããwinery 1.0ã¯ãããæ°å¹´ã§æé«ã®åºæ¥æ ãã¨è¨ããã ãããHackageã¸æ¥ãï¼
å ±åã¯GitHubãããã¯Haskell-jp Slackã¾ã§ã