![](/img/trans.png)
[英]Parsing/exporting arbitrarily nested JSON objects to maps in 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.