2016-03-30 8 views
0

私は既存のintライブラリを "bigint"という新しいライブラリに拡張しようとしています。私はint型のリストとしてbigint型のデータ型を保持しています。基本的には、任意のintを受け取り、その各桁をintリストの別のセルに格納してからこのintリストを返す関数(getbigintと呼ぶ)が必要です。私が入力したのであれば:smlで新しい署名を定義する方法

getbigint 9 

それは私を与える必要があります。

val it =[9]:bigint 

をどのように私はこれを達成することができますか?当分の間、私はこの関数への入力が1桁のintであると仮定します。ここまで私が今まで行ってきたことがあります:

signature BigInt = 
    sig 
     type bigint = int list 
     val getbigint: int -> bigint 
    end; 

structure struct_bigint : BigInt = 
    struct 
     fun getbigint (i:int) = 
      let 
       val h = [i]:bigint 
      in h 
      end 
    end 
(*val j = getbigint 9;*) 

これはエラーを出しています。

答えて

1

シグネチャは何も実装しません。それは外の世界に構造がどのように見えるかを記述します。それを仕様と考えてください。それにマッチする構造体は、シグネチャ内の要素の実装を提供する必要があります。あなたのコードを実行したときに次のエラーを取得することに注意してください:

Error: unmatched type specification: bigint 

SMLを使用すると、構造体の対応する実装にマッチしていない署名で何かを持っていることを検出しました。

最小限の修正が単にfun getbigintの実装前に、ラインに構造体の定義で

type bigint = int list 

を追加することです。これにより、行が許可されます

val j = struct_bigint.getbigint 9; 

を動作させることができます。しかし、それは少し愚かな行を持っているように見えるかもしれない

type bigint = int list 

2回 - 署名で1回、そして構造内で1回。そして、いくつかの点で、です。

実装の詳細は実際に署名に属していません。 の署名にはtype bigintがあり、構造のint listの実装はである方が理にかなっています。これにより、構造体を使用するコードがまったく影響を受けないように、実装について後で(リストではなく配列を使用したいと考えている)実装を変更することができます。ような何か:

signature BIGINT = 
    sig 
     type bigint 
     val getbigint: int -> bigint 
    end 

structure BigInt : BIGINT = 
    struct 
     type bigint = int list 

     fun getbigint (i:int): bigint = [i];    
    end; 

私はそれに結合letは少し無意味に思えたので、getbigintの実装をクリーンアップ、および署名(すべて大文字)の名前と構造のためのより多くの慣用的なものを選びました(大手とキャメルケース資本)。

最後に、getbigint 9はそのまま使用できないことに注意してください。)BigInt.getbigint 9

2)

3現在のスコープ内の名前にgetbigintその意図した意味を与えるためにラインval getbigint = BigInt.getbigintを使用して、使用する:明示的に修飾名を使用)

1:あなたは3つのいずれかを行うことができます構造体の定義をトップレベルに移動するにはopen BigInt行、その後はgetbigint 9が期待通りに機能します。

私がSMLでプログラミングを始めたとき、たくさんの構造体を開いていました(Char、 `Listなど)。これを無意識に行うと、遅かれ早かれ、構造を開いて名前の衝突を引き起こすバグが発生します。そのため、私はほぼ常にアプローチ1)または2)を使用します。

関連する問題