问题描述
考虑这个例子(来自):import Data.Char
capWord [] = []
capWord(h:t)= toUpper h:map toLower t
capitalize = unwords。地图capWord。单词
有没有一种很好的方法来抽象来回转换,例如 unwords。 F 。字?我可以提出的最好的是
class Lift a b | a - > b其中
up :: a - > b
down :: b - > a
实例Lift String [String]其中
up =单词
下=单词
解除::(提升a b)=> (b→b)→> a - >
提升f =下跌。 F 。
capitalize = lifted(map capWord)
但感觉不是很好灵活且需要 MultiParamTypeClasses , FunctionalDependencies , TypeSynonymInstances 和 FlexibleInstances - 这可能是一个指标,它在顶部略微 。
我会说最好的答案是不,因为抽象并不会为你买东西。事实上,你的解决方案远没有灵活性:在作用域中只能有一个 Lift String [String] 的实例,并且有更多的方法可以将字符串拆分为字符串列表只是 words / unwords (这意味着你会开始向混合中投掷新类型或更加神秘的扩展)。保持简单 - 原来的大写就好了。
或者,如果你真的坚持:
取消::(a - > b,b - > a) - > (b→b)→> a - >
提升(上涨,下跌)f =下跌。 F 。 (字,单词)
onLines =取消(行,非行)
大写= onWords $地图capWord
从概念上讲,和typeclass一样,除非没有滥用typeclass机器。
Consider this example (from https://codereview.stackexchange.com/questions/23456/crtitique-my-haskell-function-capitalize):
import Data.Char capWord [] = [] capWord (h:t) = toUpper h : map toLower t capitalize = unwords . map capWord . words
Is there a good way to abstract over the "back and forth" transformation, e.g. unwords . f . words? The best I could come up was
class Lift a b | a -> b where up :: a -> b down :: b -> a instance Lift String [String] where up = words down = unwords lifted :: (Lift a b) => (b -> b) -> a -> a lifted f = down . f . up capitalize = lifted (map capWord)
but it feels not very flexible, and needs MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances and FlexibleInstances - which might be an indicator that it goes slightly over the top.
I'd say the best answer is "no, because abstracting over that doesn't buy you anything". In fact your solution is far less flexible: there can be only one instance of Lift String [String] in scope and there are more ways to split string into a list of strings than just words/unwords (which means you'll start throwing newtypes or even more arcane extensions into the mix). Keep it simple — the original capitalize is just fine the way it is.
Or, if you really insist:
lifted :: (a -> b, b -> a) -> (b -> b) -> a -> a lifted (up, down) f = down . f . up onWords = lifted (words, unwords) onLines = lifted (lines, unlines) capitalize = onWords $ map capWord
Conceptually the same thing as your typeclass, except without abusing typeclass machinery so much.
这篇关于如何对“来回”进行抽象转型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!