如何对“来回”进行抽象转型? [英] How to abstract over a "back and forth" transformation?

查看:117
本文介绍了如何对“来回”进行抽象转型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个例子(来自 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。地图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.

这篇关于如何对“来回”进行抽象转型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆