1

我阅读了这篇关于如何创建自定义 Prelude 库的博文。图书馆可以在这里找到。它所做的其中一件事是禁止String。它还定义了一个用于自动字符串转换的函数(here)。我已OverloadedStrings在 cabal 文件中启用。

在使用这个库之前,我有:

data Point = Point Int Int
instance Show Point where
  show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")"

使用图书馆后,它说:“show' is not a (visible) method of class显示”

所以我求助于创建一个自定义函数来显示数据类型:

showPoint :: Point -> LText
showPoint (Point x y) = toS ("(" ++ show x ++ ", " ++ show y ++ ")")

编译器说使用toS, "(", show是模棱两可的,但我不明白为什么。我必须做类似这里提议的事情吗?

编辑:

必须禁用 OverloadedStrings 并将代码更改为以下内容:

showPoint :: Point -> LText
showPoint (Point x y) = toS "(" <> show x <> toS ", " <> show y <> toS ")"

想知道是否可以在不禁用 OverloadedStrings 的情况下做同样的事情,所以我不必toS为每个String.

4

2 回答 2

2

这对我有用:

{-# LANGUAGE OverloadedStrings #-}

module Test where

import Protolude
import qualified Base as PBase

data P = P Int

instance PBase.Show P where
  show (P x) = "a P " ++ show x

更新

protolude 的实现show是一个普通的函数(参见 Protolude.hs 的末尾):

show :: (Show a, StringConv String b) => a -> b
show x = toS (PBase.show x)

所以你需要一个PBase.Show实例才能使用 protolude 的 show 功能。

protoludeshow也可以返回任何字符串类型,因此您不会通过定义 PBase.show 实例来强迫其他人使用 String。

更新#2

您可以从以下位置导入 typeclassshow函数GHC.Show

{-# LANGUAGE NoImplicitPrelude #-}

import Protolude
import GHC.Show

data P  = P Int

instance Show P where
  show (P x) = "<-- P " ++ GHC.Show.show x ++ " -->"

main = print (P 123)
于 2016-06-05T17:21:56.287 回答
1

这可能是由以下原因引起的:

  • show可以产生任何类似字符串的类型
  • 字符串文字被重载,因此它们是任何类似字符串的类型
  • toS可以接受许多不同的类型

如果是这样,编译器不知道要选择哪种中间类字符串类型,并引发歧义错误。

于 2016-06-05T17:11:33.057 回答