一步一步替换

时间:2015-05-21 23:55:53

标签: haskell substitution

我在理解以下功能时遇到了问题

lines :: String -> [String]
lines ""        = []
lines ('\n':cs) = "": lines cs
lines (c:cs)    = case lines cs of
                   [] -> [[c]]
                   (l:ls) -> (c:l):ls

我想了解"f\no"调用函数时的功能。我正在寻找一个工具,显示每个替换步骤,以便更好地理解该功能。我手动尝试(并在写这篇文章时得到了解决方案),但我不确定我是否正确。

lines ('f':"\no")  = case lines "\no" of
                      [] -> [['f']]
                      (l:ls) -> ('f':l):ls

- > lines "\no"

lines ('\n':"o")   = "": lines "o"

- > lines "o"

lines ('o':"")     = case lines "" of
                      [] -> [['o']]
                      (l:ls) -> ('o':l):ls

- > lines ""

lines ""           = []

- >返回[]

lines ('o':"")     = case [] of
                      [] -> [['o']]
lines ('o':"")     = [['o']]

- >返回["o"]

lines ('\n':cs)     = "": ["o"]

- >返回"": ["o"]

lines ('f':"\no")  = case "":["o"] of
                      (l:ls) -> ('f':l):ls

lines ('f':"\no")  = ('f':""):["o"]
                   = ["f", "o"]

是吗?

3 个答案:

答案 0 :(得分:2)

我试图在没有阅读你的解决方案的情况下解决这个问题。当我一半的时候,我头疼并开始进一步阅读你的帖子。据我所知,一切都与你所写的一致。剩下的部分很好地解释了你。

从我所知道的并回答你的问题,是的,你是对的。

答案 1 :(得分:2)

我建议您在代码中使用Debug.Trace.trace来跟踪调用并返回值:

trace :: String -> a -> a

例如:

import Debug.Trace

traceL l t v = trace (replicate l ' '++t) v  

lines' :: String -> Int -> [String]
lines' ""        l = traceL l"lines \"\" = " $ traceL l "[]" []
lines' ('\n':cs) l = 
    let v = (traceL l ("lines ('\\n':"++show cs++") = ") ""):lines' cs (l+1)
    in  (traceL l (show v) v)

lines' (c:cs) l = 
    let v = case traceL l ("lines ("++show c++":"++show cs++") = ") $ lines' cs (l+1) of [] -> [[c]];(x:xs) -> (c:x):xs
    in (traceL l (show v) v)

l参数是调用级别。 希望它会有所帮助

答案 2 :(得分:1)

nu,对lines的递归调用将堆叠,因此表达式将从右向左处理,将参数返回到先前的调用。类似的东西:

"o" will pass a "" as cs returning a []

'o' will then become ["o"] returning a (l:ls)

"\n" will become a "", cons'd into the ["o"], returning ["","o"], another (l:ls)

'f' will finally become the c in (c:l):ls meaning ('f':""):["o"] producing ["f","o"]