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 = unfoldrN((B.length bs)* 2)unfld 0
答案 0 :(得分: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)
虽然由于getLine
和putStrLn
出现不明确而无法编译。您可能需要import qualified
。主要观察:
无论关键字本身在哪里,Do-blocks,let-blocks等都从内部的第一个内容开始。 E.g。
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
因此,我经常在开始阻止之前给do
和where
他们自己的行。在上面给出的示例中,您可以看到即使我将do-block移动到名称更长或更短的函数中,缩进也不会改变。
开始缩进的同一块中的行是前一行的延续。防护是一个延续,因此需要缩进,同样where
的let赋值需要比赋值本身缩进。
in do
是多余的,所以我删除了它(或者,只是缩进它也会有用)。答案 1 :(得分:1)
错误消息不是由缩进错误引起的,而是由于排序错误引起的。您似乎已在where
- 块的中间插入do
- 块。这不起作用。整个do
- 块,包括最终表达式,应该在where
块之前。
也就是说,你的where
块内的定义中有缩进错误:你需要缩进模式保护。
答案 2 :(得分:1)
您的外部do
仅由input <- getLine
组成,因为以下令牌let
的入口次数已经低于input
(这无论如何都没有意义,但......)
也许你的意思是:
do input <- getLine
let ....
let ..... where
unfld ....
但人们只能猜测。使用indendation来明确哪些项目属于一起,以及哪些项目是其他项目的子项目。上面的风格相当模糊了这一点。另外,你不应该写
foo x y z
| ..... =
因为编译器会看到
foo x y z; | ... =