2015-05-21 5 views
1

У меня есть проблемы в понимании следующей функцииШаг за шагом Замена

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"] 

Является ли это правильно?

+0

выглядит хорошо да - для инструмента: вы можете в основном использовать отладчик в GHCi к шагу через него;) – Carsten

+0

кстати: это такой вопрос, на самом деле весьма прискорбно для SO - как вы можете видеть вы получаете ответы «Да, я так думаю» - вот почему я собираюсь проголосовать за закрытие этого – Carsten

+0

Возможно, https://stevekrouse.github.io/hs.js/ может помочь, но я не знаю точно, сколько Haskell поддерживается этим инструментом. – chi

ответ

2

Я попытался понять это в своей голове, не прочитав ваше решение. Когда я был на полпути, я получил головную боль и начал читать дальше ваш пост. Насколько я понял, все было в соответствии с тем, что вы написали. Оставшаяся часть была хорошо объяснена вами.

Из того, что я могу сказать и ответить на ваш вопрос, да, вы правы.

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) 

Параметр л уровень вызова. Надеюсь, это поможет

+0

Wow. Это немного потрясающе для моих основных знаний.Но я попробовал это на своем ghci и получил следующее сообщение об ошибке: Ошибка: «Ошибка синтаксического анализа (возможно, неправильный отступ или несогласованные скобки)». – froehli

+0

Я исправил его, но должен был поставить оператор case на одной строке. – Damien

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"] 
Смежные вопросы