locked
タプルに対するtype abbreviation(型略称)について RRS feed

  • 質問

  • type hoge = string * int
    let f (x:hoge) = ()
    


    とタプルに対してtype abbreviation(型略称)を使用した場合の、関数fのシグネチャについて質問です。

    Visual Studioのエディタ上でカーソルをあてたり、F# Interactiveへ送ったりして確認すると、関数fのシグネチャは次のようになります。

    val f : string * int -> unit
    


    しかし、私は、

    val f : hoge -> unit
    


    となるべきではないかと思います。タプルではなく単一の型に型略称を使用した場合は、型略称がシグネチャに表れるからです。

    val f : string * int -> unit となるのは正しい挙動でしょうか?もしかしたら、不具合なのではと思ってしまったのですが。。。

    また、val f : hoge -> unit と認識させるための方法はありますか?

    2011年8月26日 17:54

回答

  • OCamlで試してみました。

    # type hoge = string * int ;;
    type hoge = string * int
    # let f (x : hoge) = () ;; val f : hoge -> unit = <fun>

    OCamlはちゃんと出来てますね。笑

    F#のほうも仕様書を確認してみましたが、関係しそうな記述は見当たりませんでした。
    ちなみに関数以外でしたら普通に使えます。

    > type Hoge = string * int ;;
    type Hoge = string * int
    
    > let a : Hoge = "hello", 1 ;;
    val a : Hoge = ("hello", 1)
    

    仕様かもしれませんが、どちらかというとバグっぽい雰囲気・・・。
    中村さんは英語力が高いので、米MSDNフォーラムで質問し直してみると、中の人から回答をもらえるかもしれませんね。 
    2011年8月30日 12:37
  • > また、val f : hoge -> unit と認識させるための方法はありますか?

    シグネチャ ファイル(.fsi ファイル)を用いれば可能です。

     

    > ところで、代替策を思いつきました。型略称の代わりに判別共用体を使うのはどうでしょう。

    はい、それがよさそうに思えます。下記 URL もあわせてご参考ください。

    http://stackoverflow.com/questions/2855735

     

    あんまり関係ないですが、C# への typedef の導入は「ときすでに遅し」だ、という話を思い出しました。

    http://www.atmarkit.co.jp/fdotnet/insiderseye/20060215cscommunity/cscommunity_02.html


    2011年9月1日 14:32

すべての返信

  • OCamlで試してみました。

    # type hoge = string * int ;;
    type hoge = string * int
    # let f (x : hoge) = () ;; val f : hoge -> unit = <fun>

    OCamlはちゃんと出来てますね。笑

    F#のほうも仕様書を確認してみましたが、関係しそうな記述は見当たりませんでした。
    ちなみに関数以外でしたら普通に使えます。

    > type Hoge = string * int ;;
    type Hoge = string * int
    
    > let a : Hoge = "hello", 1 ;;
    val a : Hoge = ("hello", 1)
    

    仕様かもしれませんが、どちらかというとバグっぽい雰囲気・・・。
    中村さんは英語力が高いので、米MSDNフォーラムで質問し直してみると、中の人から回答をもらえるかもしれませんね。 
    2011年8月30日 12:37

  • 仕様かもしれませんが、どちらかというとバグっぽい雰囲気・・・。
    中村さんは英語力が高いので、米MSDNフォーラムで質問し直してみると、中の人から回答をもらえるかもしれませんね。 

    回答ありがとうございます。

    やっぱりバグっぽい雰囲気ありますよね。

    英語力。。。はアレなんですが、フィードバックしてみます。Connectに投げれば英語に変換してくれるのでそっちを使ってしまおうかな。

     

    ところで、代替策を思いつきました。型略称の代わりに判別共用体を使うのはどうでしょう。

    type Hoge = Hoge of string * int
    
    

    上の判別共用体を定義すれば、次のように使ったりできますし、

    let f (x:Hoge) = ()

    引数でパターンマッチングしてもきれいに表現できます(最近のお気に入り)。

    let g (Hoge(a, b)) = ()
    

    上で示した関数fもgもシグネチャは、意図通り Hoge -> unit になるので自分がやりたかったことに近い感じです。

    これでシグネチャが複雑になったとしてもすっきり書きやすくなります!

    2011年9月1日 2:28
  • > また、val f : hoge -> unit と認識させるための方法はありますか?

    シグネチャ ファイル(.fsi ファイル)を用いれば可能です。

     

    > ところで、代替策を思いつきました。型略称の代わりに判別共用体を使うのはどうでしょう。

    はい、それがよさそうに思えます。下記 URL もあわせてご参考ください。

    http://stackoverflow.com/questions/2855735

     

    あんまり関係ないですが、C# への typedef の導入は「ときすでに遅し」だ、という話を思い出しました。

    http://www.atmarkit.co.jp/fdotnet/insiderseye/20060215cscommunity/cscommunity_02.html


    2011年9月1日 14:32
  • > シグネチャ ファイル(.fsi ファイル)を用いれば可能です。

     

    ありがとうございます。
    シグネチャファイルに次のように記述したら関数fのシグネチャが意図通りになりました。
    type hoge = string * int
    val f : hoge -> unit
    

     

    > はい、それがよさそうに思えます。下記 URL もあわせてご参考ください。

     

    判別共用体を使う例が出ていますね。
    参考になります。

     

    > あんまり関係ないですが、C# への typedef の導入は「ときすでに遅し」だ、という話を思い出しました。

     

    F#の型略称は限定的ですよね(F#の中だけしか使えず、実行時には型略称で定義した型が使えない)。
    .NET Frameworkレベルでそういった機能がないから仕方ないといったところでしょうか。



    2011年9月2日 9:37