是否可以使 Traversal 成为 IsString 的实例
Is it possible to make Traversal an instance of IsString
我想使用字符串文字作为遍历,但我有点迷失了类型。
是否可以创建此实例?
import Control.Lens
import Data.Aeson
import Data.Aeson.Lens
import Data.String
import Data.Default
{- Having:
key' :: AsValue t => Text -> Traversal' t (Maybe Value)
_JSON :: (ToJSON a, FromJSON a) => Traversal' t a
-}
instance (AsValue t, FromJSON v, ToJSON v, Default v) => IsString (Traversal' t v) where
fromString k = key' (fromString k) . non (toJSON def) . _JSON
要在 State monad 中实现这样的功能:
"some-key" .= (3 :: Int)
通用量化类型实例有问题。谢谢!
我无法编译你的代码,但这应该无关紧要。我假设你有一个
类型的函数
fromStringTraversal :: (AsValue t, FromJSON v, ToJSON v, Default v)
=> String -> Traversal' t v
fromStringTraversal = undefined
然后要编写您的实例,只需将 Traversal'
的定义内联到实例头中即可。这是有效的,因为实例中的任何类型变量无论如何都被隐式地普遍量化。
{-# LANGUAGE RankNTypes, FlexibleInstances, GADTs #-}
instance (a ~ a', b ~ b', AsValue b, Default a, FromJSON a, ToJSON a, Applicative f)
=> IsString ((a -> f a') -> b -> f b') where
fromString = fromStringTraversal
a ~ a', b ~ b'
约束可以从上下文移动到实例头,但这种方式可以提供更好的类型推断。那么
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
-- Infered type:
-- test :: (AsValue s, MonadState s m) => m ()
test = "some-key" .= (3 :: Int)
我想使用字符串文字作为遍历,但我有点迷失了类型。 是否可以创建此实例?
import Control.Lens
import Data.Aeson
import Data.Aeson.Lens
import Data.String
import Data.Default
{- Having:
key' :: AsValue t => Text -> Traversal' t (Maybe Value)
_JSON :: (ToJSON a, FromJSON a) => Traversal' t a
-}
instance (AsValue t, FromJSON v, ToJSON v, Default v) => IsString (Traversal' t v) where
fromString k = key' (fromString k) . non (toJSON def) . _JSON
要在 State monad 中实现这样的功能:
"some-key" .= (3 :: Int)
通用量化类型实例有问题。谢谢!
我无法编译你的代码,但这应该无关紧要。我假设你有一个
类型的函数fromStringTraversal :: (AsValue t, FromJSON v, ToJSON v, Default v)
=> String -> Traversal' t v
fromStringTraversal = undefined
然后要编写您的实例,只需将 Traversal'
的定义内联到实例头中即可。这是有效的,因为实例中的任何类型变量无论如何都被隐式地普遍量化。
{-# LANGUAGE RankNTypes, FlexibleInstances, GADTs #-}
instance (a ~ a', b ~ b', AsValue b, Default a, FromJSON a, ToJSON a, Applicative f)
=> IsString ((a -> f a') -> b -> f b') where
fromString = fromStringTraversal
a ~ a', b ~ b'
约束可以从上下文移动到实例头,但这种方式可以提供更好的类型推断。那么
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
-- Infered type:
-- test :: (AsValue s, MonadState s m) => m ()
test = "some-key" .= (3 :: Int)