首页 > 解决方案 > 使用 DefaultSignatures 时未解析类型

问题描述

我正在default为一系列实例的定义而苦苦挣扎。由于某种原因,GHC 不解析类型。

{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}

module Main where

import           Control.Monad.State.Strict (liftIO)
import qualified Data.Aeson                 as JSON
import qualified Data.ByteString.Lazy       as B
import           Data.Maybe
import           GHC.Generics               (Generic)

dataDir :: FilePath
dataDir = "data/"

class LoadFromFile a where
  loadFromFile :: FilePath -> IO a
  default loadFromFile :: JSON.FromJSON a => FilePath -> IO a
  loadFromFile filename = fmap (fromJust . JSON.decode) $ B.readFile ( dataDir ++ filename )

requirementsHistoryFile :: FilePath
requirementsHistoryFile = "requirementsHistory.json"

data Requirement = Contains String deriving (Show, LoadFromFile, JSON.FromJSON, Generic)
type RequirementsHistory = [Requirement]

displayRequirementsHistory :: RequirementsHistory -> IO ()
displayRequirementsHistory requirementsHistory = mapM_ (putStrLn . show) requirementsHistory

main :: IO ()
main = do
  requirementsHistory <- liftIO $ loadFromFile requirementsHistoryFile
  displayRequirementsHistory requirementsHistory

出现以下错误,不清楚原因:

Main.hs:31:35: error:
    • No instance for (LoadFromFile RequirementsHistory)
        arising from a use of ‘loadFromFile’
    • In the second argument of ‘($)’, namely
        ‘loadFromFile requirementsHistoryFile’
      In a stmt of a 'do' block:
        requirementsHistory <- liftIO
                                 $ loadFromFile requirementsHistoryFile
      In the expression:
        do requirementsHistory <- liftIO
                                    $ loadFromFile requirementsHistoryFile
           displayRequirementsHistory requirementsHistory
   |
31 |   requirementsHistory <- liftIO $ loadFromFile requirementsHistoryFile
   | 

任何想法为什么会发生此错误?

标签: haskelltypeclass

解决方案


您的deriving子句产生一个实例LoadFromFile Requirement,但您需要LoadFromFile RequirementsHistoryie。LoadFromFile [Requirement]. 我相信您的默认签名将允许仅通过以下方式定义它:

instance LoadFromFile RequirementsHistory

或者,您可以定义一个更通用的实例,例如:

instance JSON.FromJSON a => LoadFromFile a

这可能会让您遇到重叠实例的麻烦。


推荐阅读