假设我想创建一个新的数据类型并使构造函数可以显示,只是小写而不是大写的定义.例如:
data Day = Monday | Tuesday | Wednesday| Thursday | Friday | Saturday | Sunday
Run Code Online (Sandbox Code Playgroud)
通过添加派生显示,ghci会将它们打印为"星期一,星期二......等" 为了让它显示"星期一,星期二......等",我试图制作一个特殊的show实例:
import Data.Char
strToLower :: [Char] -> [Char]
strToLower (x:xs) = toLower x : strToLower xs
strToLower [] = []
instance Show Day where
show d = strToLower (show d)
Run Code Online (Sandbox Code Playgroud)
show的第一次出现应该指定我新修改的show函数(每次打印时都会调用),而对于第二次我打算通常派生的show版本,从构造函数名称到String.
当然这不起作用(循环定义),因为ghci对我的"show"这个词的单独含义没有任何线索,但我无法弄清楚如何让他知道这个区别,因为这两个版本都需要命名为show ,第一个是因为这是打印调用和第二个因为它是一个预定义的haskell函数,它可以给我一个构造函数名称的字符串.我试过了
show d = strToLower ((showsPrec 0 d) "")
Run Code Online (Sandbox Code Playgroud)
但这归结为相同的循环定义,至少这是我从ghci卡在循环中的猜测.
我理解为什么构造函数名称需要以大写字母开头,但显示小写字母应该不是问题,是吗?我知道我可以单独为每个案例定义我的show函数,例如show Monday = "monday" show Tuesday = "tuesday"etc,但我只是以星期几为例,我的真实数据类型由64个构造函数组成,所以我认为它会更优雅以某种方式解决它.
是否有可能深入了解show的haskell定义并更改该代码的副本?这是我能想到的唯一可能的解决方案,但我不知道该怎么做,如果可能的话.可能不是.所以其他解决方案也非常受欢迎!
感谢您抽出宝贵时间
杰勒(哈斯克尔初学者)
Jul*_*ter 11
您实际上可以使用Typeable和Data类来完成此操作.
要执行此操作,您需要DeriveDataTypeable扩展,使用-XDeriveDataTypeable或通过将以下行放在定义您的类型的文件的开头:
{-# LANGUAGE DeriveDataTypeable #-}
Run Code Online (Sandbox Code Playgroud)
您现在可以导入所需的模块:
import Data.Data
import Data.Typeable
Run Code Online (Sandbox Code Playgroud)
并从中获得Typeable和Data:
data Day = Monday | Tuesday | Wednesday| Thursday | Friday | Saturday | Sunday
deriving (Typeable, Data)
Run Code Online (Sandbox Code Playgroud)
现在您可以使用toConstr获取构造函数表示:
instance Show Day where
show = strToLower . showConstr . toConstr
Run Code Online (Sandbox Code Playgroud)
但是看看你是否真的想要的其他答案,而不是简单地使用showDay函数或你自己的类型.
Show该类的实例应该以这样的方式工作,即您可以复制粘贴其输出并将其用作Haskell代码.如果您现在拥有小写构造函数,则这些将不起作用.他们会使用这种newtype方法,
data DayInternal = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
newtype Day = Day DayInternal
monday = Day Monday
tuesday = Day Tuesday
wednesday = Day Wednesday
thursday = Day Thursday
friday = Day Friday
saturday = Day Saturday
sunday = Day Sunday
instance Show Day where
show (Day d) = strToLower $ show d
Run Code Online (Sandbox Code Playgroud)
当然,这会给你留下你可能不喜欢的冗余.您可以使用Template Haskell自动构建它,但我怀疑这是非常值得的.
我真正想到的是你想要的根本不是一个Show实例,而是某种漂亮的打印.你可以自己动手
class MyNiceShow s where
myNiceShow :: s -> String
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
deriving (Show)
instance MyNiceShow Day where
myNiceShow d = strToLower $ show d
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1097 次 |
| 最近记录: |