私は、学習の練習としてハスケルに簡単なツールを書こうとしていて、わからないものに遭遇しました。ここにそれを示す簡単なサンプルがあります。関数の定義と型をハスケルで理解する
idMap :: a -> a
idMap x = map id x
main = do
print $ idMap [1, 2]
私の理解によれば、この例では、実行時に[1, 2]
をコンパイルして印刷する必要があります。しかし、次のメッセージでコンパイルに失敗した場合:それは一種の意味が
source_file.hs:2:18: error:
• Couldn't match expected type ‘[b0]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for:
idMap :: forall a. a -> a
at source_file.hs:1:10
• In the second argument of ‘map’, namely ‘x’
In the expression: map id x
In an equation for ‘idMap’: idMap x = map id x
• Relevant bindings include
x :: a
(bound at source_file.hs:2:7)
idMap :: a -> a
(bound at source_file.hs:2:1)
、map
の署名が(a -> b) -> [a] -> [b]
であることを考えるので、入力タイプは、必ずしも出力型と同じではなく、の署名id
はa -> a
なので、確かにmap id
は(a -> a) -> [a] -> [a]
の署名を持っていますか?
私が実際に理解していない第2の部分は、すべてのタイプ(上記のa
とb
)がInteger
であることを考えると、これが例外である理由です。 idMap
の署名がa -> a
であるので、出力タイプが入力タイプと異なることが予想される状況で使用される場合は、コンパイル例外のみが存在するはずです。
最後に、このコードを実際にどのように動作させるのですか?私の実際のコードはもう少し複雑で、出力タイプはコード内の他の場所での入力タイプと一致していますので、idMap
のシグネチャを変更したくない場合は、何を書き込む必要があるかを知りたいその署名付きの関数です。
'map id 'の型は' a - > [a] 'ですが、' a - > a'と指定します。 – Lee