2016-05-04 17 views
0

愚かな疑問を抱いて申し訳ありませんが、あるデータベースパッケージから別のデータベースパッケージへの変換を行うためにHaskellに戻ってきましたが、これを正しく行う方法について少し困惑しています。 Database.SQLite3モジュールにおいてタイプ同義語の機能

は、

execWithCallback :: Database -> Text -> ExecCallback -> IO() 

次に、コールバックは、タイプExecCallback マイ愚かなテストコードコンパイルを持つ関数である

type ExecCallback = ColumnCount -> [Text]-> [Maybe Text] -> IO() 

として定義されているタイプのexecWithCallbackあります正しく実行されます。

{-# LANGUAGE OverloadedStrings #-} 

import Database.SQLite3 
import Data.Text 

cb :: ColumnCount -> [Text] -> [Maybe Text] -> IO() 
cb n cnl ct = do print $ cnl !! 1 
        return() 

main = do 
    dh <- open "fileinfo.sqlite" 
    execWithCallback dh "select * from files;" cb 
    close dh 

しかし、タイプのポイントは何ですか?そして、cbExecCallbackであると指定するにはどうすればいいですか?

+2

型署名を短くすることができます!そして、それが1であることを指定する必要はありません。それだけです!しかし、好きなら 'cb :: ExecCallback'と書くことができます。私は特にそれを推奨しませんでした。それを書くことはそれをより明瞭にする。そしてあなたはあまりにも多くの疑問符を必要としません! – dfeuer

答えて

2

ハスケルでtypeと入力した場合は、のという同義語を定義します。あなたの例では、ExecCallbackはタイプColumnCount -> [Text]-> [Maybe Text] -> IO()の単なるエイリアスであることを意味しますが、これらは互換性があります。

あなたは

cb :: ExecCallback 
cb n cnl ct = do print $ cnl !! 1 
        return() 

に次の行に

cb :: ColumnCount -> [Text] -> [Maybe Text] -> IO() 
cb n cnl ct = do print $ cnl !! 1 
        return() 

を変更することができ、すべてがまだあるとして動作します。コードを短くて読みやすくすることができます。

もう一つの良い例は

type String = [Char] 

in Preludeです。ほとんどの場合[Char]の代わりに通常Stringを使用すると思います。しかし、あなたはどちらも自由に使えます。任意の型iの値のためのシンク何かのために

type Sink i = ConduitM i Void 
type Consumer i m r = forall o. ConduitM i o m r 

Sink iConduitM i Voidより道より読みやすいようだ:

別(全く無関係)の例では、いくつかのtype synonymsが大きな違いを生むconduitパッケージです。 Consumerと同じです。

+0

もう一つの良い例は 'lens'です。これはスーパー・ギャナル型の同義語を持っています。最も簡単なものの1つは 'タイプレンズt a b =全てのfである。ファンクターf =>(a - > f b) - > s - > f t'。 – dfeuer

+0

@dfeuerオクラホマ、そこに奇妙な型の同義語があると確信していますが、私はこの単純なケースをソールする方法を学んだのはうれしいです:-)とにかく、ありがとう! –

関連する問題