makeLenses
制約付きのデータ型でテンプレートを使用できますか? できる場合、その方法は? Template Haskellについてすべて読まずに、そうしたいと思います。
GHC には次の例があります。
{-# LANGUAGE TemplateHaskell, FlexibleInstances, UndecidableInstances, NoMonomorphismRestriction #-}
module Main (main) where
import Control.Lens
import Control.Monad.Reader -- mtl
class Class1 a where
someThing :: a -- just some filler
instance (Num a) => Class1 a where
someThing = 3
data (Class1 a) => Foo a = Foo { _field1 :: a }
makeLenses ''Foo
main :: IO ()
main = putStrLn . show $ runReader (view field1) $ Foo { _field1 = 5 }
これにより、次のコンパイル エラーが発生します。
Could not deduce (Num a1) arising from a use of ‘Foo’
from the context (Profunctor p, Functor f)
bound by the type signature for
field1 :: (Profunctor p, Functor f) =>
p a (f a1) -> p (Foo a) (f (Foo a1))
at src/main.hs:58:1-16
Possible fix:
add (Num a1) to the context of
the type signature for
field1 :: (Profunctor p, Functor f) =>
p a (f a1) -> p (Foo a) (f (Foo a1))
In the second argument of ‘iso’, namely ‘Foo’
In the expression: iso (\ (Foo x_a3NK) -> x_a3NK) Foo
In an equation for ‘field1’:
field1 = iso (\ (Foo x_a3NK) -> x_a3NK) Foo
だから私はそれが生成したと思います:
field1 :: Lens' (Foo a) a
私も試してみましmakeFields
たmakeClassy
が、役に立ちませんでした。
私はこれを回避できることを知っています:
field1 :: (Class1 a) => Lens' (Foo a) a
field1 = lens _field1 (\ foo val -> Foo { _field1 = val })
makeLenses
しかし、テンプレート Haskellでそれを行う方法はありますか?
GHC バージョン 7.8.4 とlens
バージョン 4.8 を使用しています。
(注: makeLenses について同様の質問があったことは知っていますが、それでも機能させることができませんでした。私は haskell の初心者です。)