1

私の考えでは、型パラメーターaはリストを含む何でもかまいません。なぜこれが機能しないのですか?

fun :: a -> a
fun [] = []

Haskell はこのコードをコンパイルしたくありません。なぜだろう。

Couldn't match expected type `a' with actual type `[t0]'
 `a' is a rigid type variable bound by
    the type signature for fun :: a -> a

I can make it work rewriting the signature like this

fun :: [a] -> [a]

But this is not something that I am looking for as I wanted to keep the function polymorphic. I wonder how id works on empty lists.

Prelude> :t id
id :: a -> a
Prelude> id []
[]
4

2 に答える 2

7

型変数何でもかまいませんが、あなた (呼び出し先) は何を選択することはできません。

いくつかの用語に寄り道しましょう。Haskell のデフォルトは、いわゆる「普遍的な数量化」です。これは、特定の型変数がすべてのインスタンス化によって満たされる可能性があることを意味します。呼び出し元は、必要なものを何でも入力できます。

だからあなたが言うとき

fun :: forall a. a -> a
fun [] = []

「考えられるすべての typeaについて、それをリストのように扱う」と言っているようなものです。これは明らかにナンセンスです!

型クラスを使用するアドホック ポリモーフィズムのようなものが必要なようです。

{-# LANGUAGE OverlappingInstances, FlexibleInstances #-}
class Id a where
  myId :: a -> a
instance Id a where
  myId = id
instance Id [a] where
  myId [] = [ undefined ] -- special case
  myId xs = xs
于 2013-11-15T03:20:56.283 に答える
0

書くことができると考えてみましょう (そうではありませんが、楽しみのためです):

fun :: a -> a
fun [] = []

これは、パターン マッチングによって、

fun _ = error "Nonwritten error!"

これは、次の 2 つのことを意味します。

1) 次のような追加データ型が存在します。

data Universe = forall a. a

しかし、このデータは Haskell には存在しません! そして、ここにはデータコンストラクターがありません

2) これは、署名が正しくないことを意味します。

fun :: Universe -> Universe
于 2013-11-15T22:59:52.890 に答える