是否可以使Traversal成为IsString的实例

Pav*_*vel 3 haskell types aeson haskell-lens

我想使用字符串文字作为遍历,但我在类型中有点迷失.是否可以创建此实例?

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
Run Code Online (Sandbox Code Playgroud)

在State monad中实现这样的目标:

"some-key" .= (3 :: Int)
Run Code Online (Sandbox Code Playgroud)

通用量化类型实例的问题.谢谢!

use*_*038 5

我无法编译你的代码,但这无关紧要.我假设你有一个类型的功能

fromStringTraversal :: (AsValue t, FromJSON v, ToJSON v, Default v) 
                    => String -> Traversal' t v 
fromStringTraversal = undefined
Run Code Online (Sandbox Code Playgroud)

然后编写您的实例,只需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
Run Code Online (Sandbox Code Playgroud)

a ~ a', b ~ b'限制可能会从上下文实例头部移动的,但这种方式提供更好的类型推断.然后

{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}

-- Infered type:
-- test :: (AsValue s, MonadState s m) => m ()
test = "some-key" .= (3 :: Int)
Run Code Online (Sandbox Code Playgroud)