個人的には、私はRecordWildCards
に行き、それを1日と呼びます。風に注意を投げると種類を変える倍を取得するために、動的タイプを使用します。しかし、ここでこれを行うには、別の興味深いハック - しかし、方法は、いくつかの状況において有用であり得る、です!
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Dynamic (dynApp, fromDynamic, toDyn)
import Data.List (foldl')
import Data.Typeable (Typeable)
-- Add the 'Typeable' instance to enable runtime type information.
data Zone = Zone
{ zId, zOwnerId, zPodsP0, zPodsP1, zPodsP2, zPodsP3 :: Int
} deriving (Show, Typeable)
mkZone :: [String] -> Maybe Zone
mkZone = fromDynamic . foldl' dynApp (toDyn Zone) . map (toDyn . readInt)
where
-- This type-specialised 'read' avoids an ambiguous type.
readInt :: String -> Int
readInt = read
これは、タイプのZone
コンストラクタから開始します。そして、その型を変更して、入力から読み出された各Int
に連続的にそれを適用し
Int -> Int -> Int -> Int -> Int -> Int -> Zone
を:
Int -> Int -> Int -> Int -> Int -> Zone
Int -> Int -> Int -> Int -> Zone
Int -> Int -> Int -> Zone
Int -> Int -> Zone
Int -> Zone
Zone
そして、それは動作します:
> mkZone ["1", "2", "3", "4", "5", "6"]
Just (Zone {zId = 1, zOwnerId = 2, zPodsP0 = 3, zPodsP1 = 4, zPodsP2 = 5, zPodsP3 = 6})
あなたも、いくつかの引数を指定すると、実行時のキャストが失敗したので
は、あなたがNothing
取得:
> mkZone ["1", "2", "3", "4", "5", "6", "7"]
*** Exception: Type error in dynamic application.
Can't apply function <<Zone>> to argument <<Int>>
簡単です:
> mkZone ["1", "2", "3", "4", "5"]
Nothing
をしかし、あなたはあまりにも多くの引数を指定する場合は、例外を取得しますMaybe
代わりに投げを返すdynApply
代わりにdynApp
を用いて固定しました。そして、限り、あなたはMaybe
で作業しているように、あなたにも、エラーを解析処理するためにText.Read.readMaybe
を使用する場合があります:本当のために
{-# LANGUAGE DeriveDataTypeable #-}
import Control.Monad ((<=<))
import Data.Dynamic (Dynamic, dynApply, fromDynamic, toDyn)
import Data.List (foldl')
import Data.Typeable (Typeable)
import Text.Read (readMaybe)
data Zone = Zone { … } deriving (Show, Typeable)
mkZone :: [String] -> Maybe Zone
mkZone = fromDynamic <=< foldl' go (Just (toDyn Zone)) . map readInt
where
go :: Maybe Dynamic -> Maybe Int -> Maybe Dynamic
go mAcc mx = do
acc <- mAcc
x <- mx
dynApply acc $ toDyn x
readInt :: String -> Maybe Int
readInt = readMaybe
をしかし、おそらくこれをしません。