为什么我用嵌套的let / guard块得到缩进错误

时间:2014-02-18 01:29:32

标签: haskell

我正在编写一个转置函数作为现实世界haskell的练习。但是,我非常沮丧,因为某种方式haskell无法解析(或者我写错了)我的代码。

这是问题所在:

transpose :: [Char] -> [Char]
transpose x = 
        let splitted = lines x
            transposed = tpose splitted
            tpose :: [String] -> [String]
            tpose xs 
                | null xs = []
                | all null xs = []
                | otherwise = let
                    safeHead "" = ''
                 >> safeHead x = head x
                    safeTail "" = ""
                    safeTail x = tail x
                        in (map safeHead xs):(tpose (map safeTail xs)) 


        in unlines transposed

解析错误位于>>。整个邮件是parse error (possibly incorrect indentation or mismatched bracked)

我甚至试图不用重写代码,例如:

        tpose :: [String] -> [String]
        tpose xs 
            | null xs = []
            | all null xs = []
            | otherwise = (map safeHead xs):(tpose (map safeTail xs)) 
                    where
                        safeHead "" = ''
                        safeHead x = head x
                        safeTail "" = ""
                        safeTail x = tail x

但仍然无法修复缩进错误。如何正确编写嵌套的let / while / guard?

2 个答案:

答案 0 :(得分:3)

错误发生在上一行 - ''不是有效字符:

                    safeHead "" = ''
                    safeHead x = head x

答案 1 :(得分:1)

正如已经指出的那样,语法错误实际上是''中的空字符safeHead

让我们重构一下。 safeHeadtpose不使用transpose中的任何数据,因此为了清晰起见,可以不加内联

safeHead "" = ' '
safeHead x = head x
safeTail "" = ""
safeTail x = tail x

tpose可以使用模式匹配,我们可以删除几个括号:

tpose :: [String] -> [String]
tpose [] = [] 
tpose xs 
    | all null xs = []
    | otherwise = map safeHead xs : tpose (map safeTail xs)

离开

transpose :: [Char] -> [Char]
transpose x = 
        let splitted = lines x
            transposed = tpose splitted
        in unlines transposed

现在很明显transpose中的所有内容只是lines,然后tpose然后是unlines,所以我们应该使用合成:

transpose :: [Char] -> [Char]
transpose = unlines . tpose . lines