簡體   English   中英

通過在Haskell中部分應用來減少列表

[英]Reduction of list through partial application in Haskell

對於具有多個參數的函數,是否有一些功能更強大的map? 因此,精簡列表的長度將是length of original / number of arguments ...

tuple a b = (a, b)
map' tuple [1, 2, 3, 4]
> [(1, 2), (3, 4)]

mul a b c = a * b * c
map' mul [1, 2, 3, 4, 5, 6]
> [3, 120]

我試圖為自己寫一個,但是似乎無法接受任何數量的參數的功能。

我想為可變數量的參數提供通用版本,因為每次自己編寫一個會花費一些時間,並且不會使用循環融合。

最簡單的解決方案是只為您需要的每個Arity生成一個輔助函數,例如,針對Arity 3函數:

map3 :: (a -> a -> a -> b) -> [a] -> [b]
map3 f (x : y : z : rest) = f x y z : map3 f rest
map3 f _ = []

將它們放在實用程序模塊中,以便您可以根據需要導入它們。 如果您想變得復雜,可以使用TemplateHaskell,CPP宏甚至類型類來生成它們,但是要小心,不要將這個簡單的練習變成a牛刮胡子聚會。

你的例子:

interact $ unlines . fmap foo . tuple . lines

然后可以表示為:

interact $ unlines . map2 foo . lines

假設foo具有簽名foo :: String -> String -> String

我不同意定義這樣的東西的精神,但是僅僅出於它的狹och性,我正在努力嘗試它。 這是一個有效的解決方案,但僅適用於單態類型。 我正在研究是否可以將其轉換為涉及類型族的東西,這些類型族也不需要亂用類型注釋。

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}

class Consumer f a b where
  consume :: f -> [a] -> Maybe (b,[a])

instance {-# OVERLAPPABLE #-} Consumer b a b where
  consume b xs = Just (b,xs)

instance {-# OVERLAPPING #-} Consumer f a b => Consumer (a -> f) a b where
  consume f [] = Nothing
  consume f (x:xs) = consume (f x) xs

map' :: Consumer f a b => f -> [a] -> [b] 
map' f xs = case consume f xs of
                Nothing -> []
                Just (b,xs') -> b : map' f xs'

並進行測試

> map' ((+) :: Int -> Int -> Int) ([1,2,3,4] :: [Int]) :: [Int]
[3,7]
> map' (id :: Int -> Int) ([1,2,3,4] :: [Int]) :: [Int]
[1,2,3,4]

編輯

經過一番思考,我認為不可能有更好的解決方案(沒有依賴類型)。 我之所以要到處添加類型標注的是,我沒有辦法告知GHC的,我已經提供的兩個實例消費者其實我都不會想的唯一實例(是密閉式班甚至一個東西嗎?)我可以”提取功能依賴性。 第二個問題也是為什么我不能將其重寫為類型族。 在一個側面說明,雖然,注釋功能參數可以看起來要好很多,現在我們有TypeApplicationsmap' ((+) @Int) ([1..9] :: [Int])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM