所以从瞥一眼hackage我可以看到5个漂亮的打印库:
哦等等,那是6?6个漂亮的印刷图书馆......没等了,我们又来了.
无论如何,他们都是Wadler-Leijen,当然除了HughesPJ.我的理解是WL更简单,更快,因此可能是新代码的首选.
wl-pprint和wl-pprint-extras看起来是一样的...我不知道后者的"额外"是什么,或者"Free"在这里意味着什么(模块是Text.PrettyPrint.Free).
wl-pprint-terminfo和ansi-wl-pprint似乎都是具有ANSI终端颜色和诸如此类的变体,并且似乎是等效的,除了wl-pprint-terminfo没有任何文档.
wl-pprint-text当然使用Text.我不知道实际上有多快差异.
令我担心的是,他们中的许多人都有很多版本.这意味着他们已经添加了功能,修复了错误等等.但他们是否都修复了相同的错误?我倾向于支持ansi-wl-pprint,因为它有文档,并且它的最后一次上传是在2012年,并且有一些版本暗示作者仍在使用它.
但我不确定.有人有什么建议吗?而且我相信其他人同意5个几乎但不完全复制粘贴的模块可以做一些整合......
所以说我有一节课:
class C a where
reduce :: a -> Int
Run Code Online (Sandbox Code Playgroud)
现在我想将其打包成数据类型:
data Signal = forall a. (C a) => Signal [(Double, a)]
Run Code Online (Sandbox Code Playgroud)
由于存在量化,我可以在信号上调用C方法,但信号不公开类型参数:
reduceSig :: Signal -> [(Double, Int)]
reduceSig (Signal sig) = map (second reduce) sig
Run Code Online (Sandbox Code Playgroud)
现在因为C有很多方法,我自然而然的下一步就是拉出'reduce'函数,这样我就可以替换任何方法:
mapsig :: (C a) => (a -> a) -> Signal -> Signal
mapsig f (Signal sig) = Signal (map (second f) sig)
Run Code Online (Sandbox Code Playgroud)
输入错误!无法推断(a1~a).进一步思考,我认为它的含义是'f'是某个C实例的函数,但我无法保证它与信号中的C实例相同,因为类型参数是隐藏的!我想要它,我明白了.
那么这是否意味着不可能推广reduceSig?我可以忍受这个,但我已经习惯于在haskell中自由地分解函数了,不得不编写样板文件感觉很奇怪.另一方面,我想不出任何方式来表达一个类型等于Signal内部的类型,而不是给Signal一个类型参数.
尝试这个新的stackoverflow事情,正如建议:)这不是真正的haskell特定,但它在haskell中最清楚.
这是一个偶然出现的模式:一个函数需要两个对称处理的参数.mappends经常有这个属性.一个例子:
-- | Merge sorted lists of ranges.
merge :: (Ord n) => [(n, n)] -> [(n, n)] -> [(n, n)]
merge [] r2 = r2
merge r1 [] = r1
merge r1@((s1, e1) : rest1) r2@((s2, e2) : rest2)
| e1 < s2 = (s1, e1) : merge rest1 r2
| e2 < s1 = (s2, e2) : merge r1 rest2
| s1 >= s2 && e1 <= e2 = merge rest1 r2 -- 1 within 2
| …Run Code Online (Sandbox Code Playgroud) 我想做一些源代码转换(自动导入列表清理),我想保留注释和格式.关于解析器,我听到了一些关于解析器的内容,我认为是ghc解析器.
看起来我可以通过hs-src-exts Language.Haskell.Exts.Annotate和它的SrcSpans从文件中提取出来.我认为SrcsSpanInfo只涵盖解析的部分,但理论上我可以通过查看两者之间的内容来找出评论.但它没有详细记录,并且没有我能找到的辅助函数,看起来很麻烦,例如,没有简单的方法可以打印出包含格式和注释的解析表达式.所以我认为这并不意味着以这种方式使用,它只是为了突出文件中的代码或其他东西.我的印象是作者打算使用注释来支持这一点,但从来没有解决过这个问题.
看起来既不是yi也不是leksah这样做.我觉得HaRe可能会,但它不是超级记录.那里有一个haskell解析器吗?
所以,如果我有两种大致相同的数据类型,我可以这样写:
data A t = A1 | A2 | A3 | A4 (B t)
data B t = B1 | B2 | B3 | B4 t
type AX = A X
type AY = A Y
Run Code Online (Sandbox Code Playgroud)
现在很容易通过AX和AY编写函数,或者如果他们不关心则编写'A t'.但那我该怎么写转换呢?
convert :: AX -> AY
convert (A4 (B4 x)) = A4 (B4 (xToY x))
convert ax = ay -- type error
Run Code Online (Sandbox Code Playgroud)
所以现在我需要手工编写所有其他情况,即使它们都不依赖于类型参数.更糟糕的是,虽然我可以在不依赖于"A {}"的参数的情况下匹配构造函数,但如果我需要这些参数来重构数据,这是不可能的.
有没有更好的方法来做到这一点?我觉得GADT应该能够表达这一点,但很难看出如何从不依赖它的术语中消除类型变量.我想我必须有A1 A2等单独的类型,然后我会失去封闭和案例检查...此外我不想手写Show,Eq和Typeable!我能想到的另一种方法是重新排列整个结构以隔离变化的部分,即
data A t = Independent | B4 t
data Independent = A1 | A2 | ...
Run Code Online (Sandbox Code Playgroud)
但是这使得数据的每次其他使用都变得笨拙,从而有利于一个转换功能. …