在where子句中键入hole不起作用

时间:2015-04-26 15:02:31

标签: haskell

我有以下

readStatement :: String -> IO  [Transaction]
readStatement path = do
   csvData <- readFile path
   return $ catMaybes (map _ (splitOn "\r" csvData))

GHC为洞[Char] -> Maybe Transaction找到以下类型。 现在,如果我给这个洞命名并进入where子句

readStatement :: String -> IO  [Transaction]
readStatement path = do
   csvData <- readFile path
   return $ catMaybes (map process (splitOn "\r" csvData))
   where process = _ 

GHC找不到新行的类型,但给出:

Found hole ‘_’ with type: t
Where: ‘t’ is a rigid type variable bound by
           the inferred type of process :: t at Statement.hs:63:11
Relevant bindings include
  process :: t (bound at Statement.hs:63:11)
  path :: String (bound at Statement.hs:60:15)
  readStatement :: String -> IO [Transaction]
    (bound at Statement.hs:60:1)
In the expression: _
In an equation for ‘process’: process = _
In an equation for ‘readStatement’:
    readStatement path
      = do { csvData <- readFile path;
             return $ catMaybes (map process (splitOn "\r" csvData)) }
      where
          process = _

代码是完全等价的,那么类型推断怎么会给出相同的结果呢? (我正在使用GHC 7.8.3)

1 个答案:

答案 0 :(得分:4)

在以下代码中

let x = something
in f x

x = something的类型推断不考虑f。也就是说,推断出something的类型,推广到多态类型,x获得该类型。这可能会为x分配一个比f所需类型更通用的类型。

更具体地说,在

let x = \y->y
in  x "hello"

我们推断出多态绑定x :: forall a. a->a。 请注意,String尚未显示。

我猜GHC就是在let定义上执行类型推断之后打印出类型的孔信息。在已发布的示例中,

do one
   two
where process = _

我们推断_ :: t而不查看上下文并打印该类型。如果您想要更专业(单态)类型,请尝试改为

(\process -> do
   one
   two
) _

上面,我们不使用letwhere,因此只会推断出单态类型。