2016-10-21 3 views
2

タイプシステムで次のように簡単に行う方法はありますか?タイプレベルのレコード内のすべてのフィールドに関数を適用する

data Product = Product { 
    id :: ProductId 
    , name :: Text 
    , sku :: SKU, quantity :: Int 
    , description :: Maybe Text 
    } 

data Omittable a = Omit | Present a 
type ProductWithOmittableFields = Omittable Product 

-- ProductWithOmittableFields is now equivalent to:\ 
-- 
-- data ProductWithOmittableFields = ProductWithOmmitableFields { 
--  id :: Omittable ProductId 
-- ,name :: Omittable Text 
-- ,sku : : Omittable SKU 
-- ,quantity :: Omittable Int 
-- ,desciption :: Omittable (Maybe Text) 
-- } 

これは、基本的には、コンテナ(ファンクタ?)タイプ・レベルでのレコードのすべてのフィールドに適用されるのいくつかの並べ替えです。

この考え方は、拡張可能なレコードライブラリでよりよく表現されますか?

編集ユースケースは、ユーザーによって変更されたフィールドのセットを表すUIレイヤーからProductWithOmittableFieldsが得られることです。我々は、DBからProductを取得する、と私たちはProduct

+1

"この考えは、拡張可能なレコードライブラリでよりよく表現されていますか?"あなたはそれのような何かをすることができます "ジェネリックスソップ"と呼ばれるライブラリがあります。これらの他の質問を参照してください:http://stackoverflow.com/questions/39020787/is-there-a-way-to-apply-maybe-constructor-to-each-field-of-record-with-generics and http: /stackoverflow.com/questions/38248692/whats-a-better-way-of-managing-large-haskell-records – danidiaz

答えて

4

の新しい値に可能な方法を得るためにそれらをマージします:

import Control.Functor.Identity 

data Product k = Product { 
    id :: k ProductId 
    , name :: k Text 
    , sku :: k SKU 
    , quantity :: k Int 
    , description :: k (Maybe Text) 
    } 

data Omittable a = Omit | Present a 
type ProductWithOmittableFields = Product Omittable 
type ProductWithRegularFields = Product Identity 

例:

testOmit :: ProductWithOmittableFields 
testOmit = Product 
    { id = Present someProductId 
    , name = Omit 
    ... } 

testReg :: ProductWithRegularFields 
testReg = Product 
    { id = Identity someProductId 
    , name = Identity someText 
    ... } 

このアプローチは、唯一持っているが通常のケースではIdentityで各フィールドを折り返す小さな不便さ。

+0

値レベルで「Product Identity」から「ProductWithRegularFields」を取得する最も簡単な方法は何ですか?ランタイム)? –

+0

@SaurabhNandaあなたは何もする必要はありません、まったく同じタイプです。上の例では、新しい型 'data T = ... 'を宣言するのではなく、型同義語' type T = 'を使用しました。 – chi

+0

私に言い換えましょう。各フィールドが 'Identity x'ではない' Product'値を取得する方法? –

関連する問題