2016-08-15 70 views
0

我有一个功能,需要10个String参数和一些重构期间,代码的部分已经改变,从而现在这些参数最终成为Text当调用该函数时:如何将函数应用于其他函数的每个参数?

fxn :: String -> ... -> IO (Int, String) 
fxn a b c d e f g h i j = do something 

... 

-- Get parameters for fxn 
let a = "blah" :: Text 
... 
fxn a b c ... 

理想情况下,我可以重构所有的使用Text的代码,但目前这是乏味和不理想的。我也可以很容易地添加T.unpack的地方,我得到了我的函数的参数:

let a = T.unpack ("blah" :: Text) 

但同样,这是不理想的,因为这发生在几个不同的地方对大量的参数,我希望保留代码清理比拥有数十个T.unpack声明无处不在。

haskell有没有办法组合函数,使参数变形,如(fxn . T.unpack) a b c ...,或将解压缩函数应用于f函数的每个参数?这看起来像是一个简单的组合问题,但我一直无法找到解决方案。

+1

10个参数?这似乎有点过分,你应该肯定重构......关于你的问题:你能提供你正在寻找的函数的类型吗? – mb21

+0

它似乎过分,但它是一个服务器和处理JSON参数,所以它很可能只会不幸成长。我无法找到更好的方法来管理这部分代码。我绝对可以提供类型签名,但你的意思是哪个函数? – jkeuhlen

+2

如果你改变你的代码在一个地方使用'Text',但在其他地方留下'String',那么你1.遇到你遇到的问题,并且2.失去对性能改进的所有希望。这不是一个Haskell问题 - 这是一个设计问题。统一使用Text或String,或者使用函数的重载版本,这两种类型的操作符(这会杀死类型推断),或者不使用10个字符串参数,因此不会产生添加'T.unpack'的成本。时间结束。 – user2407038

回答

4

对于处理参数扩散,您可能会喜欢record parameter模式。这也使得在保持向后兼容性的同时公开具有相同名称的新API变得方便。

对于这个问题的提出,它通常是最简单的定义很短的适配器是这样的:

fxnNew :: Text -> ... -> IO (Int, Text) 
fxnNew = ... 

fxn :: String -> ... -> IO (Int, String) 
fxn a ... i = fmap (fmap T.unpack) (fxnNew (T.pack a) ... (T.pack i)) 
+0

感谢您的链接,这非常有帮助。这看起来稍微干净一些,但我希望避免为这种转换定义新的功能。无论哪种方式,感谢您的输入! – jkeuhlen

相关问题