gpt4 book ai didi

haskell - 带有 DataKinds 的 FromJSON 实例

转载 作者:行者123 更新时间:2023-12-02 16:34:27 28 4
gpt4 key购买 nike

尝试使用 TypeLits 对数据类型进行 JSON 反序列化时,我遇到了以下问题:

Couldn't match type ‘n’ with ‘2’      ‘n’ is a rigid type variable bound by        the instance declaration at test.hs:14:10      Expected type: aeson-0.11.2.1:Data.Aeson.Types.Internal.Parser                       (X n)        Actual type: aeson-0.11.2.1:Data.Aeson.Types.Internal.Parser                       (X 2)

How would be the correct syntax to allow Nat generically in the FromJSON instance in the following example:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}

import GHC.TypeLits
import Data.Aeson
import Control.Monad (mzero)

data X (n :: Nat) where
A :: Integer -> X 1
B :: Integer -> X 2

instance FromJSON (X n) where
parseJSON (Object o) = do
v <- o .: "val"
t <- o .: "type"
case t of
"a" -> return $ A v
"b" -> return $ B v
parseJSON _ = mzero

最佳答案

由于您显然无法知道要在编译时反序列化的类型,因此需要将确切的类型隐藏在存在值中,然后通过模式匹配恢复。我通常使用通用的 Some 类型来隐藏幻像类型。

{-# LANGUAGE PolyKinds #-}

data Some (t :: k -> *) where
Some :: t x -> Some t

现在您可以将实例编写为

instance FromJSON (Some X) where
parseJSON (Object o) = do
v <- o .: "val"
t <- o .: "type"
case (t :: String) of
"a" -> return $ Some $ A v
"b" -> return $ Some $ B v
parseJSON _ = mzero

但是,您还需要启用 FlexibleInstances 扩展。

关于haskell - 带有 DataKinds 的 FromJSON 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41201843/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com