これはできません。 Haskellでは無限型(データ型ではない)が明示的に禁止されており、必要なコードを生成するのが容易で、エラーが発生します(たとえば、try let foo = (42, foo) in foo
)。
もちろん、newtype
とdata
で作成することはできますが、コンストラクタ内外の値を明示的にラップしてラップ解除する必要があります。
これは明示的な設計上の決定です:無限型では、コンパイラが拒否したいと思う誤った表現が許されなければならず、より多くのプログラムが許可されなければならないので、以前は明白に型定義されたプログラム明示的な型の注釈を必要とするがあいまいになります。したがって、トレードオフが行われます。これは、そうでない場合よりも型システムから多くの助けを得ることの代償として、無限型のかなりまれな用途について明示することを要求します。
ががは型クラスを使用して、あなたのeat
機能に似たものを定義する方法ですが、あなたはそれに3を得た場合にのみ、それは停止することはできません、言った:あなたはそれを3かできないを与えてくれたかどうかは、実行時にのみ決定され、コンパイル時に型が決定されます。
class Eat a where
eat :: a
instance Eat Integer where
eat = 3
instance (Eat r) => Eat (a -> r) where
eat _ = eat
キャッチは、あなたがそれを使用する場合、正確に型を指定する必要があることです:
*Main> eat 1 foldr()
<interactive>:6:1:
Ambiguous type variable `t0' in the constraint:
(Eat t0) arising from a use of `eat'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: eat 1 foldr()
In an equation for `it': it = eat 1 foldr()
*Main> eat 1 foldr() :: Integer
3
しかし、ここでは両方
Integer
、そしてちょうどその引数を食べる関数とすることができるオーバーロードされた値です
はInteger
となる可能性がありますが、同じ表現ではeat 1
とeat 1 foldr
を同じように使用したのと同じように、別の関数でもかまいません。繰り返しますが、柔軟な型付けを行いますが、返す型を明示的に指定する必要があります。
オーバーロードされた数値リテラル(42
がNum
のインスタンスのいずれかのタイプとすることができる)のように、過負荷状態に型クラスを考えてみてください。
haskellの無限型は大丈夫です。 **技術的に**無限のタイプを使用していてもまだ動作していない回避策があるかどうかを知りたいのですが – Karan
コメントを投稿したときと同じように答えを広げました。私はそれがその追加の質問に答えるのを助けることを願っています:) – ehird
したがって、常に3を返し、任意のタイプ(a - >(b - > .. Integer)を食べる – Karan