2017-01-04 13 views
2

は、ここに私が持っているものだタイプの家族を持つレコード用レンズを作るために:どのようにコンパイルされていない、

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE StandaloneDeriving #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE TemplateHaskell #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE FunctionalDependencies #-} 

import Data.Text as T 
import Data.Int (Int64) 
import Control.Lens 

type family Incoming validationResult baseType 
type instance Incoming Validated baseType = baseType 
type instance Incoming ValidationErrors baseType = Either [T.Text] baseType 

data Validated 
data ValidationErrors 

data Tag = Tag {unTag :: T.Text} deriving (Eq, Show) 

data NewTag f = NewTag 
    { 
    ntClientId :: Incoming f Int64 
    , ntTag :: Incoming f Tag 
    } 

$(makeLensesWith abbreviatedFields ''NewTag) 

コンパイルエラー:

27 3 error   error: 
• Illegal type synonym family application in instance: 
    Incoming f_a1Kvx Int64 
• In the instance declaration for 
    ‘HasClientId (NewTag f_a1Kvx) (Incoming f_a1Kvx Int64)’ (intero) 
27 3 error   error: 
• Illegal type synonym family application in instance: 
    Incoming f_a1Kvx Tag 
• In the instance declaration for 
    ‘HasTag (NewTag f_a1Kvx) (Incoming f_a1Kvx Tag)’ (intero) 

答えて

3

ここでの問題は、makeLensesForがしようとするということです次のようにインスタンスを生成します。

instance HasClientId (NewTag f) (Incoming f Int64) where 
    .... 

これは、instを作成できないためエラーですタイプファミリアプリケーションの結果に対するance。これを避けるには、fの2つの選択肢のそれぞれに対してインスタンスを手動で記述することができます。

-- generate lenses _foo for each record selector foo 
-- (in this case, generates _ntClientId and _ntTag lenses) 
makeLensesWith (lensRules & lensField .~ mappingNamer (\x -> ['_' : x])) ''NewTag 

class HasClientId s a | s -> a where 
    clientId :: Lens' s a 

instance HasClientId (NewTag Validated) Int64 where 
    clientId = _ntClientId 

instance HasClientId (NewTag ValidationErrors) (Either [T.Text] Int64) where 
    clientId f a = f (ntClientId a) <&> \ntClientId' -> a { ntClientId = ntClientId' } 

class HasTag s a | s -> a where 
    tag :: Lens' s a 

instance HasTag (NewTag Validated) Tag where 
    tag = _ntTag 

instance HasTag (NewTag ValidationErrors) (Either [T.Text] Tag) where 
    tag = _ntTag 
+0

'クラスHasClientId s a | s - > a where'、パイプは何ですか?また、何のための矢印ですか?あなたはそれを説明するかもしれない何かへのリンクを投稿できますか?私はこれの説明を見たことがないし、私はかなり前に検索した。 –

+0

@Julian Leviston FunctionalDependenciesの構文です(しばしば短縮されたfundeps)。 – bennofs

+0

ありがとう。私はそれを見上げるでしょう。 –

関連する問題