How to abstract over a “back and forth” transformation?

前端 未结 5 767
栀梦
栀梦 2021-02-19 04:53

Consider this example (from https://codereview.stackexchange.com/questions/23456/crtitique-my-haskell-function-capitalize):

import Data.Char

capWord [] = []
cap         


        
5条回答
  •  生来不讨喜
    2021-02-19 05:16

    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.

提交回复
热议问题