3
import Data.ByteString as B
import Data.ByteString.Internal as I
import Data.Bits
main = do input <- getLine
      let bs = B.pack input
      let intermediatebs  =  unfoldrN ((B.length bs)*2) unfld 0
      where unfld i
      |Prelude.rem i 2 == 0 = Just (top4 $ B.index bs (i/2) , i+1)
      |otherwise =  Just (bottom4 $ B.index bs (i/2) , i+1)
      top4bits x = shiftR x 4
      bottom4bits x = x .&. 0x0F
      top4 x = convertASCIIword8 $ top4bits x
      bottom4 x = convertASCIIword8 $ bottom4bits x
      convertASCIIword8 x
      |x <= 9 = I.c2w '0' + x
      |otherwise = I.c2w 'A' + (x-10)
      let outputbs = B.map I.w2c $ intermediatebs
      in do putStrLn (outputbs)

我收到此编译错误“do”构造中的最后一条语句必须是一个表达式:let intermediatebs = unlockrN ((B.length bs) * 2) unfld 0

4

3 回答 3

5

在这里很难确切地看到你想要什么。只需更改缩进即可使您的代码解析:

import Data.ByteString as B
import Data.ByteString.Internal as I
import Data.Bits
main = do
  input <- getLine
  let bs = B.pack input
  let intermediatebs  =  unfoldrN ((B.length bs)*2) unfld 0
       where
        unfld i
          | Prelude.rem i 2 == 0 = Just (top4 $ B.index bs (i/2) , i+1)
          | otherwise =  Just (bottom4 $ B.index bs (i/2) , i+1)
        top4bits x = shiftR x 4
        bottom4bits x = x .&. 0x0F
        top4 x = convertASCIIword8 $ top4bits x
        bottom4 x = convertASCIIword8 $ bottom4bits x
        convertASCIIword8 x
          | x <= 9 = I.c2w '0' + x
          | otherwise = I.c2w 'A' + (x-10)
  let outputbs = B.map I.w2c $ intermediatebs
  putStrLn (outputbs)

尽管由于模棱两可getLineputStrLn出现而无法编译。你可能想import qualified在适当的地方。主要意见:

  • Do-blocks、let-blocks 等从它们内部第一件事的左边缘开始,不管关键字本身在哪里。例如

    do x
       y
    -- ^ because of where the x is, all future lines have to line up with it
    
    let x = ...
        y = ...
    -- ^ if you have code appearing left of here, the let-block ends
    

    于是,我经常在开始之前给自己dowhere自己的线一个块。在我上面给出的示例中,您可以看到,即使我将 do-block 移动到名称更长或更短的函数中,缩进也不会改变。

  • 同一块中开始缩进的行是前一行的延续。守卫是一个延续,所以需要缩进,同样where,对于 let 赋值需要比赋值本身进一步缩进。

  • 块末尾的in do是多余的,所以我删除了它(或者,只需缩进它也可以)。
于 2012-10-27T17:22:17.260 回答
1

您的外部do仅由以下标记组成,input <- getLine因为以下标记let的缩进程度已经低于input(无论如何这都没有意义,但是....)

也许你的意思是:

do  input <- getLine
    let ....
    let .....   where 
          unfld ....

但只能猜测。使用缩进来明确哪些项目属于一起,哪些项目是其他项目的子项目。上面的风格相当模糊了这一点。另外,你不应该写

foo x y z
| ..... = 

因为编译器会看到

foo x y z; | ... = 
于 2012-10-27T17:13:10.317 回答
1

错误消息不是由缩进错误引起的,而是由排序错误引起的。您似乎已将 -block 插入到where-block 的中间do。那是行不通的。整个do-block,包括最后的表达式,应该在该where块之前。

也就是说,您的where-block 内的定义中确实存在缩进错误:您需要缩进模式保护。

于 2012-10-27T16:48:23.350 回答