具有类型同义词的函数

时间:2016-05-04 18:53:01

标签: haskell types type-synonyms

很抱歉要问这个可能很愚蠢的问题,但是回到Haskell做一些从一个数据库包到另一个数据包的转换,我发现自己对如何正确地做这件事感到有些困惑。

Database.SQLite3模块中,有execWithCallback类型

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

现在,回调被定义为

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

即类型ExecCallback的函数 我愚蠢的测试代码编译并正确运行:

{-# 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 ??

1 个答案:

答案 0 :(得分:2)

在Haskell中,使用type定义类型同义词。在您的示例中,这意味着ExecCallback只是类型ColumnCount -> [Text]-> [Maybe Text] -> IO ()的别名,它们是可互换的。

您可以更改以下行

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

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

一切都会按原样运作。它可以使您的代码更短,更易读。

另一个好例子是

type String = [Char]

in Prelude。我敢打赌,在大多数情况下,您通常会使用String代替[Char]。但你完全可以自由使用它们。

另一个(完全不相关的)示例是conduit包,其中一些type synonyms产生了重大差异:

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

对于任何类型i的值的接收器,Sink i似乎比ConduitM i Void更具可读性。与Consumer相同。