跟着我的previous question我發現了generic-deriving包,它似乎有很多我需要的積木。實現gEnumToString
函數被簡化爲一行。但是,我正在與gEnumFromString
功能問題:如何獲得一個字符串的枚舉構造函數?
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneriC#-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
import Text.Read
import GHC.Generics
import Generics.Deriving
import Control.Lens
import Data.Default as DD
import Data.Aeson.Casing
import Data.Aeson.Types (camelTo2)
data Options = Options
{
optConstructorTagModifier :: String -> String
} deriving (Generic)
instance DD.Default Options where
def = Options
{
optConstructorTagModifier = (camelTo2 '_')
}
makeLensesWith abbreviatedFields ''Options
gEnumToString :: (ConNames (Rep a), Generic a) => Options -> a -> String
gEnumToString opt x = (opt ^. constructorTagModifier) $ conNameOf x
gEnumFromString :: forall a . (Generic a, Enum' (Rep a), ConNames (Rep a))
=> Options -> String -> Maybe a
gEnumFromString opt s = lookup s lookupTable
where
lookupTable :: [(String, a)]
lookupTable = (zipWith (,) (conNames undefined) genumDefault)
此代碼不能與下面的錯誤編譯。儘管我試圖通過使用ScopedTypeVariables
並明確提供forall a
(如答案中給出的建議之一所述)來限制conNames undefined
的類型。我究竟做錯了什麼?
168 33 error error:
• Could not deduce (Generic a0) arising from a use of ‘conNames’
from the context: (Generic a, Enum' (Rep a), ConNames (Rep a))
bound by the type signature for:
gEnumFromString :: (Generic a, Enum' (Rep a), ConNames (Rep a)) =>
Options -> String -> Maybe a
at /Users/saurabhnanda/projects/vl-haskell/.stack-work/intero/intero784UVH.hs:(163,1)-(164,47)
The type variable ‘a0’ is ambiguous
These potential instances exist:
instance Generic (Either a b) -- Defined in ‘GHC.Generics’
instance forall a k (b :: k). Generic (Const a b)
-- Defined in ‘Data.Functor.Const’
instance Generic (Identity a) -- Defined in ‘Data.Functor.Identity’
...plus 31 others
...plus 201 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the second argument of ‘zipWith’, namely
‘(conNames undefined)’
In the expression: (zipWith (,) (conNames undefined) genumDefault)
In an equation for ‘lookupTable’:
lookupTable = (zipWith (,) (conNames undefined) genumDefault) (intero)
可能的重複[爲什麼這個函數在where子句中使用範圍類型變量不是typecheck?](https://stackoverflow.com/questions/36989329/why-does-this-function-that-uses- a-scoped-type-variable-in-a-where-clause-not-ty) –