тип передачи для декодирования json в haskell - PullRequest
4 голосов
/ 07 августа 2020

Я думаю, что я подхожу к этой проблеме принципиально неправильно, но я не уверен, как найти элегантное решение в Haskell.

Я хотел бы написать функцию, которая анализирует строка JSON в какой-то тип Haskell. Однако я не знаю, как передать тип в мою функцию (что я не думаю, что смогу это сделать).

Например, я хотел бы сделать что-то вроде этого:

data Foo = Foo { _a :: String } deriving (Generic, ToJSON, FromJSON)
data Bar = Bar { _b :: String } deriving (Generic, ToJSON, FromJSON)

parseSomething :: (FromJSON a) => a -> Maybe a
parseSomething a = (decode "..some json string...") :: Maybe a

Возможно ли это, или я неправильно думаю о проблеме?

На данный момент я получаю ошибку определения типа:

    • Could not deduce (FromJSON a1) arising from a use of ‘decode’
      from the context: FromJSON a
        bound by the type signature for:
                   foo :: forall a. FromJSON a => a -> Maybe a
        at src/Plumbing/Types.hs:60:1-35
      Possible fix:
        add (FromJSON a1) to the context of
          an expression type signature:
            forall a1. Maybe a1
    • In the expression: decode "{\"_a\":\"foo\"}" :: (Maybe a)
      In an equation for ‘foo’:
          foo a = decode "{\"_a\":\"foo\"}" :: (Maybe a)
   |
61 | foo a = decode "{\"_a\":\"foo\"}" :: (Maybe a)

1 Ответ

4 голосов
/ 07 августа 2020

Для этого вы можете использовать расширение application :

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}

import Data.Aeson
import GHC.Generics

data Foo = Foo { _a :: String } deriving (Show, Generic, ToJSON, FromJSON)
data Bar = Bar { _b :: String } deriving (Show, Generic, ToJSON, FromJSON)

parseSomething :: (FromJSON a) => Maybe a
parseSomething = decode "{ \"_a\": \"Hello\" }"

main :: IO ()
main = putStrLn $ show (foo, bar)
  where
    foo = parseSomething @Foo
    bar = parseSomething @Bar

, но, честно говоря, я не вижу никакой выгоды от возможности писать

foo = parseSomething @Foo
bar = parseSomething @Bar

поверх

foo = parseSomething :: Maybe Foo
bar = parseSomething :: Maybe Bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...