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 intermediabs = unfoldrN((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)

getLineあいまいでputStrLn発生するため、コンパイルされませんが。必要に応じて行うことができimport qualifiedます。主な所見:

  • Do-block、let-blockなどは、キーワード自体がどこにあるかに関係なく、その中の最初のものの左端から始まります。例えば

    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最後にあるのは冗長だったので、削除しました(または、インデントするだけでも機能します)。
于 2012-10-27T17:22:17.260 に答える
1

エラーメッセージは、順序付けエラーほどインデントエラーが原因ではありません。where-blockの途中に-blockを挿入したようですdo。それは機能しません。do最終式を含むブロック全体がブロックの前に来る必要がありwhereます。

とはいえ、-block内の定義にインデントエラーがありますwhere。パターンガードをインデントする必要があります。

于 2012-10-27T16:48:23.350 に答える
1

次のトークンはすでに(とにかく意味がありませんが....)よりも意図されていないため、アウターdoのみで構成されます。input <- getLineletinput

おそらくあなたは意味します:

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

しかし、推測することしかできません。インデンドを使用して、どのアイテムが一緒に属し、どのアイテムが他のアイテムのサブアイテムであるかを明確にします。上記のスタイルは、これをかなり曖昧にします。また、あなたは書くべきではありません

foo x y z
| ..... = 

コンパイラが見るので

foo x y z; | ... = 
于 2012-10-27T17:13:10.317 に答える