1

私は単純な1行の機能を持っています:

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (\b -> if b == (pred (fst t)) then Nothing else Just (b, pred b)) (snd t)

それはうまくいきます:

*Main Data.List> revRange ('a', 'f')
"fedcba"

次に、 unfoldr lambda を一意の関数として抽出します。

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t)) then Nothing else Just (b, pred b)) (snd t)

今、私は奇妙なエラーがあります:

Couldn't match type `Char' with `(Char, Char)'
Expected type: (Char, Char) -> Maybe (Char, (Char, Char))
  Actual type: (Char, Char) -> Maybe (Char, Char)
In the first argument of `unfoldr', namely `fun'
In the expression: unfoldr fun t
4

1 に答える 1

7

まず、コードをフォーマットします。

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t)) 
               then Nothing 
               else Just (b, pred b)) (snd t)

次に、Hoogleunfoldrを使用するタイプを再確認します。

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]

次に、型シグネチャを に追加しfunて、GHC が問題を教えてくれるようにします。のタイプによると、 は次のタイプをunfoldr持つfun必要があります。

b ~ Char
a ~ Char

fun :: Char -> Maybe (Char, Char)

あなたはunfoldr元の例にいるのでsnd t

私は通常、小さな断片を検証するのが好きなので、 の定義を削除してfoo、型シグネチャのみを使用できます。

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t

fun:: Char -> Maybe (Char, Char)
fun b = error ""

tGHC は、 type を持っているが type(Char, Char)fun期待していると文句を言いCharます。元の例のunfoldr fun t代わりに呼び出しました。unfoldr fun (snd t)そのビットを から に移動しfunますrevRange

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun (snd t)

fun:: Char -> Maybe (Char, Char)
fun b = error ""

次に、fun再度の定義を追加します。ラムダを削除しbて、通常の引数として次のように設定できますfun

fun:: Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t)) 
          then Nothing 
          else Just (b, pred b)

すぐに、別の明らかな問題が発生します。2 つのfun引数を取りますが、署名は 1 つだけを取るべきだと言っています!

は元のラムダの定数であるため、 を部分的に適用することでtこの問題を解決できるため、最終的な答えは次のようになります。funrevRange

revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (fun t) (snd t)

fun:: (Char, Char) -> Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t)) 
          then Nothing 
          else Just (b, pred b)

あなたのコメントに対処するために、あなたは書きたいです

revRange :: (Char,Char) -> [Char]
revRange = unfoldr fun2

上記と同じアプローチを使用して、 の署名でとunfoldrが必要です。そのため、タイプが必要ですb ~ (Char,Char)a ~ Charfun2

fun2 :: ((Char,Char) -> Maybe (Char, (Char, Char)))

の定義はfun2練習問題として残しておきます。ヒントとして、ペアの最初の部分が定数であり、 が成り立つという規則を採用することをお勧めしますfst t

于 2015-03-30T12:53:43.317 に答える