簡體   English   中英

在Haskell中任意繪制許多地圖

[英]Composing arbitrarily many maps in Haskell

在Haskell中如何構成n個地圖? 我試着遞歸地做它:

composeMap 0 f = (\x -> x)
composeMap n f = (.) f (composeMap (n-1) f)

並且反復:

composeMap' n k f g =
  if n == k then g
            else composeMap' n (k+1) f (f . g)

composeMap n f = composeMap' n 0 f (\x -> x)

但無濟於事。 Haskell認為我正在構造一個無限類型。 這顯然是錯誤的,因為對於任何n> = 0,定義的函數都是有限的。

有什么建議么?

一些發布了將f視為具有以下類型簽名的解決方案:

f :: a -> a

但是,我希望此方法可以通過以下方式使f st f是多態的:

f :: a -> a'
f :: a' -> a''

特別是,我想要一個適用於功能映射的功能,並帶有可能的類型簽名:

map :: (a -> b) -> [a] -> [b]
map (polymorphic) :: ([a] -> [b]) -> [[a]] -> [[b]]

該函數編譯得很好,但是Haskell推斷出以下類型簽名,這不是我想要的:

composeMap'' :: Int -> (b -> b) -> b -> b

我什至嘗試將map封裝在monad中,但是Haskell仍然認為我正在構造一個無限類型:

composeMap n f = foldl (>>=) f (replicate n (\x -> return (map x))) 

編輯:我得到了我想要的以下模板Haskell代碼。 很甜

這是為了聲明組成的映射函數:

composeMap :: Int -> Q Dec
composeMap n
  | n >= 1    = funD name [cl]
  | otherwise = fail "composeMap: argument n may not be <= 0"
  where
    name = mkName $ "map" ++ show n
    composeAll = foldl1 (\fs f -> [| $fs . $f |])
    funcs = replicate n [| map |]
    composedF = composeAll funcs
    cl = clause [] (normalB composedF) []

這是用於內聯組成的地圖。 它更加靈活:

composeMap :: Int -> Q Exp
composeMap n = do
  f <- newName "f"
  maps <- composedF
  return $ LamE [(VarP f)] (AppE maps (VarE f))
  where
    composeAll = foldl1 (\fs f -> [| $fs . $f |])
    funcs = replicate n [| map |]
    composedF = composeAll funcs

同樣,擱置問題的人甚至一開始都不了解這個問題。

恐怕我缺少一些東西。 您的第一個實現對我來說可以編譯並正常工作(ghc 8.0.2)。

您的第二個實現未能編譯,因為您忘記了else子句中的' 這是我完整的源文件:

composeMap1 0 f = (\x -> x)
composeMap1 n f = (.) f (composeMap1 (n-1) f)

composeMap2' n k f g =
  if n == k then g
            else composeMap2' n (k+1) f (f . g)

composeMap2 n f = composeMap2' n 0 f (\x -> x)

和一些測試

λ: :l question.hs
[1 of 1] Compiling Main             ( question.hs, interpreted )
Ok, modules loaded: Main.
λ: doubleQuote = composeMap1 2 (\x -> "'" ++ x ++ "'")
λ: doubleQuote "something"
"''something''"
λ: doubleQuote = composeMap2 2 (\x -> "'" ++ x ++ "'")
λ: doubleQuote "something"
"''something''"
λ: plusThree = composeMap1 3 (+1)
λ: plusThree 10
13
λ: plusThree = composeMap2 3 (+1)
λ: plusThree 10
13

暫無
暫無

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

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