我无法声明ToJSON
我类型的实例(同义词):
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
module Argon.Types (ComplexityBlock, AnalysisResult, ResultsOptions(..)
, OutputMode(..))
where
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as BL
-- | Hold the data associated to a function binding:
-- (line number, column, function name, complexity)
type ComplexityBlock = (Int, Int, String, Int)
instance ToJSON ComplexityBlock where
toJSON (l, c, func, cc) = object [ "lineno" .= l
, "col" .= c
, "name" .= func
, "complexity" .= cc
]
-- | Represent the result of the analysis of one file.
-- It can either be an error message or a list of
-- 'ComplexityBlock's.
type AnalysisResult = Either String [ComplexityBlock]
instance ToJSON (FilePath, AnalysisResult) where
toJSON (p, Left err) = object [ "path" .= p
, "type" .= "error"
, "message" .= err
]
toJSON (p, Right rs) = object [ "path" .= p
, "type" .= "result"
, "blocks" .= rs
]
导入了bytestring包并启用了OverloadedStrings
扩展名,我认为它可以正常工作,但它没有:
/home/miki/exp/argon/src/Argon/Types.hs:31:47:
No instance for (ToJSON a0) arising from a use of ‘.=’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance ToJSON (FilePath, AnalysisResult)
-- Defined at src/Argon/Types.hs:29:10
instance ToJSON ComplexityBlock
-- Defined at src/Argon/Types.hs:17:10
In the expression: type .= error
In the first argument of ‘object’, namely
‘[path .= p, type .= error, message .= err]’
In the expression:
object [path .= p, type .= error, message .= err]
/home/miki/exp/argon/src/Argon/Types.hs:31:50:
No instance for (Data.String.IsString a0)
arising from the literal ‘error’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Data.String.IsString Value
-- Defined in ‘aeson-0.8.0.2:Data.Aeson.Types.Internal’
instance (a ~ Data.ByteString.Internal.ByteString) =>
Data.String.IsString
(attoparsec-0.12.1.6:Data.Attoparsec.ByteString.Internal.Parser a)
-- Defined in ‘attoparsec-0.12.1.6:Data.Attoparsec.ByteString.Char8’
instance Data.String.IsString
Data.ByteString.Builder.Internal.Builder
-- Defined in ‘Data.ByteString.Builder’
...plus four others
In the second argument of ‘(.=)’, namely ‘error’
In the expression: type .= error
In the first argument of ‘object’, namely
‘[path .= p, type .= error, message .= err]’
/home/miki/exp/argon/src/Argon/Types.hs:35:46:
No instance for (ToJSON a1) arising from a use of ‘.=’
The type variable ‘a1’ is ambiguous
Note: there are several potential instances:
instance ToJSON (FilePath, AnalysisResult)
-- Defined at src/Argon/Types.hs:29:10
instance ToJSON ComplexityBlock
-- Defined at src/Argon/Types.hs:17:10
In the expression: type .= result
In the first argument of ‘object’, namely
‘[path .= p, type .= result, blocks .= rs]’
In the expression:
object [path .= p, type .= result, blocks .= rs]
/home/miki/exp/argon/src/Argon/Types.hs:35:49:
No instance for (Data.String.IsString a1)
arising from the literal ‘result’
The type variable ‘a1’ is ambiguous
Note: there are several potential instances:
instance Data.String.IsString Value
-- Defined in ‘aeson-0.8.0.2:Data.Aeson.Types.Internal’
instance (a ~ Data.ByteString.Internal.ByteString) =>
Data.String.IsString
(attoparsec-0.12.1.6:Data.Attoparsec.ByteString.Internal.Parser a)
-- Defined in ‘attoparsec-0.12.1.6:Data.Attoparsec.ByteString.Char8’
instance Data.String.IsString
Data.ByteString.Builder.Internal.Builder
-- Defined in ‘Data.ByteString.Builder’
...plus four others
In the second argument of ‘(.=)’, namely ‘result’
In the expression: type .= result
In the first argument of ‘object’, namely
‘[path .= p, type .= result, blocks .= rs]’
我不明白为什么类型变量不明确。
答案 0 :(得分:4)
比较签名:
fromString :: IsString a => String -> a
toJSON :: ToJSON a => a -> Value
从技术上讲,要序列化字符串文字,您的自定义实例会使用它们的叠加:
toJSON . fromString :: (IsString a, ToJSON a) => String -> Value
注意类型变量如何从签名中消失,因此产生歧义。例如,"error"
可以很高兴String
,Value
或Text
,所有这些都有IsString
和ToJSON
个实例。
快速解决方法是通过提供显式类型签名手动解决歧义:
toJSON (p, Left err) = object [ "path" .= p
, "type" .= ("error" :: String)