在学习Haskell到数据分析的示例中键入不匹配

时间:2018-05-01 13:52:11

标签: haskell

我对Haskell(LYAH)有基本的知识,想看看这本书来扩展我的Haskell,加上我喜欢的一般话题。然而,在我遇到类型问题之前不久就已经过了:

applyToColumnInCSVFile :: ([String] -> b) -> FilePath -> String -> IO (Either String b)
applyToColumnInCSVFile func inFileName column = do
  input <- readFile inFileName
  let records = parseCSV inFileName input
  return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records
    where
      handleCSVError = Left "This does not appear to be a CSV file."

它抱怨handleCSVError应该是Text.Parsec.Error.ParseError,但实际上是[Char] b0'。

这是我试图找出这些错误消息的解决方案的问题。我实际上可以在本书中高级别地遵循代码,但是如果我在编写代码时犯了一个小错误,或者还有一些其他小问题我就不能轻易恢复。

在上面我可能会将其缩小到parseCSV的问题,因为当我检查时:

http://hackage.haskell.org/package/csv-0.1.2/docs/Text-CSV.html

它显示它可以返回ParseError,但我不知道如何解决问题。

1 个答案:

答案 0 :(得分:1)

让我们关注代码的这一部分:

    @SqsListener(value = "${oao.sqs.url}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
    public void onMessage(String serviceData, @Header("MessageId") String messageId, @Header("ApproximateFirstReceiveTimestamp") String approximateFirstReceiveTimestamp) {

        System.out.println(" Data = " + serviceData + " MessageId = " + messageId);

        repository.execute(serviceData);
}

正如@DanielWagner在评论中指出的那样,你错误引用了你的错误信息实际上是:

  

•无法匹配预期类型return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records where handleCSVError = Left "This does not appear to be a CSV file."                     实际类型parsec3.1.13.0:Text.Parsec.Error.ParseError -> Either String b

错误消息继续指向您对Either [Char] b0的定义。你没有对它应用类型,但是让我们添加一个类型来更好地理解错误信息:

handleCSVError

我正在使用一个类型的孔用于正确的组件,因为我们实际上并不关心它在这里是什么,并记住在Haskell中return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records where handleCSVError :: Either String _ handleCSVError = Left "This does not appear to be a CSV file." [Char]是相同的类型。

现在,让我们看一下either :: (a -> c) -> (b -> c) -> Either a b -> c的类型。

String的第一个参数是函数,它接受either左侧类型的某些内容,并返回输出类型。但是你已经将Either定义为没有参数的静态函数。它具有来自较大函数的handleCSVError的正确输出类型c,但未指定参数。有两种方法可以解决这个问题:

  1. 使用constEither String _
  2. 丢弃... either (const handleCSVError) ...定义中的第一个参数:

    handleCSVError