2016-08-15 69 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

相關問題