當我試圖壓縮不同長度的串列并且我不希望它們被最短的串列剪切時,出現了這個問題。這是在串列中有我想要相加或相乘的整數的背景關系中。我的問題是如何設定型別變數,使其更通用。
zipWithPadding :: a -> (a -> a -> a) -> [a] -> [a] -> [a]
zipWithPadding n f = go n f
where
go n f [] a = [f n x | x <- a]
go n f a [] = [f n x | x <- a]
go n f (x:xs) (y:ys) = f x y : go n f xs ys
目前,因為必須指定填充串列的元素,所以我必須以這種方式撰寫它們,但它引出了一個問題,即是否需要為每個背景關系定制它,還是簡單地用高階函式重新調整用途。
編輯:我想在評論中感謝克里斯的幫助。通過將上述解決方案更改為,它使底部的示例成為可能:
zipPadWith :: a -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
zipPadWith n m f = go n m f
where
go n _ f [] a = [f n x | x <- a]
go _ m f a [] = [f x m | x <- a]
go n m f (x:xs) (y:ys) = f x y : go n m f xs ys
例子是:
transposeWith :: a -> [[a]] -> [[a]]
transposeWith n [] = []
transposeWith n (ms:mss) = zipPadWith n [] (:) ms (transposeWith n mss)
它在不剪切內容的情況下轉置串列串列。
uj5u.com熱心網友回復:
如果我們zipPadWith以下列方式實作,則應用默認值作為兩個引數f將簽名約束為a -> (a -> a -> a) -> [a] -> [a] -> [a].
zipPadWith _ _ [] [] = []
zipPadWith n f (x:xs) (y:ys) = f x y : zipPadWith n f xs ys
zipPadWith n f (x:xs) [] = f x n : zipPadWith n f xs []
zipPadWith n f [] (y:ys) = f n y : zipPadWith n f [] ys
但是,如果函式采用兩個默認引數,一個在左串列不足時使用,一個在右串列不足時使用,則型別不受約束,可以是a -> b -> (a -> b -> c) -> [a] -> [b] -> [c].
zipPadWith _ _ _ [] [] = []
zipPadWith n1 n2 f (x:xs) (y:ys) = f x y : zipPadWith n1 n2 f xs ys
zipPadWith n1 n2 f (x:xs) [] = f x n2 : zipPadWith n1 n2 f xs []
zipPadWith n1 n2 f [] (y:ys) = f n1 y : zipPadWith n1 n2 f [] ys
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528489.html
上一篇:非詳盡模式例外
