2つのリスト関数を1に組み合わせますか?
-
28-10-2019 - |
質問
次の2つの関数を組み合わせるにはどうすればよいですか。
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
replaceMthNth m n v arg = replaceNth m (replaceNth n v (arg !! m)) arg
単一の関数に?
出来ますか?
解決
これはかなり恐ろしいことですが、仕事をします:
replacemn 0 0 z ((x : xs) : xss) = (z : xs) : xss
replacemn 0 n z ((x : xs) : xss) =
let (ys : yss) = replacemn 0 (n-1) z (xs : xss)
in ((x : ys) : yss)
replacemn m n z (xs:xss) = xs : replacemn (m-1) n z xss
他のヒント
関数構成
Haskellの関数は、無料で構成される場合があります。たとえば、2つの関数が与えられた場合、 f
と g
, 、それらを新しい関数に構成することができます: f . g
, 、適用されます g
議論には、適用されます f
結果に。ここで同じ方法で構成を使用できるはずです。
わかりました、ここでは、グローバルネームスペースに他の名前のある機能がありません。 where
また let
条項またはその他のグローバル機能。
{-# LANGUAGE ScopedTypeVariables,RankNTypes #-}
module Temp where
newtype Mu a = Mu (Mu a -> a)
replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth = (\h (f :: Int -> forall b . b -> [b] -> [b]) -> h f f)
( \replaceNth replaceNth' ->
-- definition of replaceMthNth in terms of some replaceNth and replaceNth'
\m n v arg -> replaceNth m (replaceNth' n v (arg !! m)) arg
)
$
-- y combinator
((\f -> (\h -> h $ Mu h) $ \x -> f $ (\(Mu g) -> g) x $ x) :: (a -> a) -> a) $
(\replaceNth ->
-- definition of replaceNth given a recursive definition
(\(n::Int) newVal xs -> case xs of
[] -> []
(x:xs) -> if n == 0 then newVal:xs else x:replaceNth (n-1) newVal xs
)
)
私は質問が何であるかをまったく理解していません:)、しかし、ここに私がそれを実装する方法があります:
modifyNth :: Int -> (a -> a) -> [a] -> [a]
modifyNth n f (x:xs)
| n == 0 = f x : xs
| otherwise = x : modifyNth (n-1) f xs
replaceNthMth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceNthMth m n v = modifyNth m (modifyNth n (const v))
これにより、リストを2回実行する必要はありません(初めて !!
, 、2回目 replaceNth
)
これは、無限のリストを備えたzipsを介したネストされたリストの概念を備えた2Dリスト構造を再構築するグロテスクな実装です。
replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth m n v ass = [[if (x,y) == (m,n) then v else a
| (y, a) <- zip [0..] as]
| (x, as) <- zip [0..] ass]
所属していません StackOverflow