Haskellでfor
関数を騙して定義しました。Haskell:上位レベル関数の変数を参照する "where"関数の型を宣言する
for :: (Ord i, Num i) => (i, i, i) -> b -> (i -> b -> b) -> b
for (init, incr, end) initState bodyFn = for' (init, initState) bodyFn
where
-- for' :: (Ord i, Num i) => (i, b) -> (i -> b -> b) -> b
for' (index, state) bodyFn | if incr > 0 then index >= end else index <= end = state
for' (index, state) bodyFn = for' (index + incr, bodyFn index state) bodyFn
正常に動作します。
> for (1, 1, 10) 0 (\i b -> i+b)
45
where
関数の型を宣言したいと思います。 (わかるように、コメントアウトされています。)コメントマーキングを削除すると、このエラーメッセージが表示されます。
Couldn't match expected type ‘i1’ with actual type ‘i’
‘i’ is a rigid type variable bound by
the type signature for:
for :: forall i b.
(Ord i, Num i) =>
(i, i, i) -> b -> (i -> b -> b) -> b
at while.hs:5:8
‘i1’ is a rigid type variable bound by
the type signature for:
for' :: forall i1 b1.
(Ord i1, Num i1) =>
(i1, b1) -> (i1 -> b1 -> b1) -> b1
at while.hs:9:11
• In the second argument of ‘(>=)’, namely ‘end’
In the expression: index >= end
In the expression: if incr > 0 then index >= end else index <= end
• Relevant bindings include
bodyFn :: i1 -> b1 -> b1 (bound at while.hs:10:23)
index :: i1 (bound at while.hs:10:9)
for' :: (i1, b1) -> (i1 -> b1 -> b1) -> b1 (bound at while.hs:10:3)
bodyFn :: i -> b -> b (bound at while.hs:6:34)
end :: i (bound at while.hs:6:19)
incr :: i (bound at while.hs:6:13)
私は問題はfor'
機能がfor
関数から変数とその変数のいずれかを比較しているという事実に関係していることを推測している - ともから変数にその変数の1を加えますfor
機能。それらは同じタイプでなければなりません。それを言う方法はありますか?あるいは、for'
の関数の型を宣言する別の方法がありますか?
ありがとうございました。
P.S.私はfor'
関数をトップレベル関数として宣言して関連する変数を渡すことができますが、この構造体を使用して有効な宣言を書く方法があるのだろうかと思います。
P.P.S本質的に同じ質問がhereと尋ねられましたが、答えはネストされた関数の宣言を取り除くことでした。どのように動作するものを書くか?
剛性型変数の不一致に対する答えは、この問題を解決しました。 Thanks – RussAbbott