Enter the hole where it doesn't work

I have the following

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

      

The GHC will find the next hole type [Char] -> Maybe Transaction

. Now if I give a name to this hole and go to the where clause

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

      

GHC cannot find the newline type, but gives:

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 = _

      

The code is strictly equivalent, and how is it that type inference does not give the same result? (I am using GHC 7.8.3)

+3


source to share


1 answer


In the following code

let x = something
in f x

      

type inference x = something

is ignored f

. That is, the type something

is inferred, generalized to polymorphic types, and x

gets this type. This can assign a x

type that is more general than the type required for f

.

More specifically, in

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

      

we output polymorphic binding x :: forall a. a->a

. Please note that it String

is not displayed yet.



I think the GHC prints information about the holes of the type at that time, only after doing type inference in the definition let

. In the example posted

do one
   two
where process = _

      

we are outputting _ :: t

without going through the context and are not printing this type. If you prefer a more specialized (monomorphic) type, try instead

(\process -> do
   one
   two
) _

      

We do not use let

or above where

, so only monomorphic types will be inferred.

+4


source







All Articles