Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Question regarding to type classes (Johannes Engels)
2. Re: Question regarding to type classes (Antoine Latter)
3. how to catch the error thrown by openFile? (Ovidiu Deac)
4. Re: Question regarding to type classes (Daniel Fischer)
5. Re: how more efficient read/write a file ? (Kyle Murphy)
6. Question regarding to type classes (Johannes Engels)
7. Re: how to catch the error thrown by openFile? (Daniel Fischer)
8. how to catch the error thrown by openFile? (Ovidiu Deac)
----------------------------------------------------------------------
Message: 1
Date: Sat, 24 Sep 2011 19:21:17 +0200
From: Johannes Engels <[email protected]>
Subject: [Haskell-beginners] Question regarding to type classes
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Dear list members,
as an exercise, I tried to define a type class for structures with
ordered key values. The key values could be numbers, but also strings.
For instance, I intend to define an address list containing records with
names as key values. So far, my type class definition contains a
function "key", which should extract the key values from the structures,
and a function which compares the key values. So I tried:
class StructsWithOrderedKeys a where
-- no default definition for key
key :: (Ord b) => a -> b
(<?) :: a -> a -> Bool
x <? y = (key x) < (key y)
Here I get the following error message from GHCI:
"Ambiguous type variable 'b' in the constraint:
'Ord b' arising from a use of 'key' ...
Probable fix: add a type signature that fixes these type variable(s)"
Could anybody explain what ambiguity arises here? As the arguments of
(<?) are of the same type, I expected also the results (key x) and (key
y) to be of the same type, which should be by the type constraint for
"key" an instance of Ord. Why I am not allowed to use "key" in the
definition of (<?) ?
I would be grateful for any hint!
Johannes
------------------------------
Message: 2
Date: Sat, 24 Sep 2011 12:42:33 -0500
From: Antoine Latter <[email protected]>
Subject: Re: [Haskell-beginners] Question regarding to type classes
To: Johannes Engels <[email protected]>
Cc: [email protected]
Message-ID:
<CAKjSnQEWXkFhUTYHSAGOH_O4wkmOysNO5jyCXY0g=30mdcc...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
On Sat, Sep 24, 2011 at 12:21 PM, Johannes Engels
<[email protected]> wrote:
> Dear list members,
>
> as an exercise, I tried to define a type class for structures with ordered
> key values. The key values could be numbers, but also strings. For instance,
> I intend to define an address list containing records with names as key
> values. So far, my type class definition contains a function "key", which
> should extract the key values from the structures, and a function which
> compares the key values. So I tried:
>
> class StructsWithOrderedKeys a where
> -- no default definition for key
> ? key :: (Ord b) => a -> b
>
> ? (<?) :: a -> a -> Bool
> ? x <? y = (key x) < (key y)
>
> Here I get the following error message from GHCI:
>
> "Ambiguous type variable 'b' in the constraint:
> 'Ord b' arising from a use of 'key' ...
> Probable fix: add a type signature that fixes these type variable(s)"
>
> Could anybody explain what ambiguity arises here? As the arguments of (<?)
> are of the same type, I expected also the results (key x) and (key y) to be
> of the same type, which should be by the type constraint for "key" an
> instance of Ord. Why I am not allowed to use "key" in the definition of (<?)
> ?
>
If a function has type:
> key :: (Ord b) => a -> b
You have declared that the type 'b' can be whatever the caller wants
(given the Ord constraint).
So in the computations:
> (key x) > (key y)
You haven't told it *which* 'b' you want to pick. And because the
return value is consumed by a polymorphic function, the type inference
engine doesn't have anything to go on.
Does that make sense?
Antoine
------------------------------
Message: 3
Date: Sat, 24 Sep 2011 20:52:24 +0300
From: Ovidiu Deac <[email protected]>
Subject: [Haskell-beginners] how to catch the error thrown by
openFile?
To: beginners <[email protected]>
Message-ID:
<CAKVsE7tcR4Cs9Tk=VZOb1jqC=gkmkpk+cx8pu0q7o74sxa9...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Given this function
f :: MyMonad String
f = do
liftIO $ putStrLn "Please enter a file name: "
name ? liftIO getLine
hFile ? liftIO $ openFile name ReadMode
content ? liftIO $ hGetContents hFile
return $ content
I would like to catch the error thrown by openFile and translate it to
my own exception type.
So first I tried this:
hFile ? (liftIO $ openFile name ReadMode) `catch` ?_ ? throwError
(KnownErr "open failed")
..but it fails because the error handler is returning a different type
then the "try block". Right?
Then I tried this:
f = do
liftIO $ putStrLn "Please enter a file name: "
name ? liftIO getLine
hFile ? (liftIO $ openFile name ReadMode ? return.Right)
`catch` ?_ ? return (Left $ KnownErr "open failed")
case hFile of
Right handle ? do
content ? liftIO $ hGetContents hFile
return $ content
Left error ? throwError error
...which also fails with
Couldn't match expected type `ErrorT MyType IO t0'
with actual type `IO a0'
In a stmt of a 'do' expression:
hFile <- (do { handle <- liftIO $ openFile name ReadMode;
return (Right handle) })
`catch`
\ _ -> return (Left $ KnownErr "open failed")
Any help is appreciated.
Thanks!
Full code here:
import Control.Monad.Error
import System.IO
data MyType = UnknownErr | KnownErr String
deriving (Show)
instance Error MyType where
noMsg = UnknownErr
strMsg str = KnownErr str
type MyMonad = ErrorT MyType IO
main = do
r ? runErrorT f
reportResult r
f :: MyMonad String
f = do
liftIO $ putStrLn "Please enter a file name: "
name ? liftIO getLine
hFile ? liftIO $ openFile name ReadMode
content ? liftIO $ hGetContents hFile
return $ content
reportResult (Right c) = putStrLn ("The content is " ? c)
reportResult (Left e) = putStrLn ("Error: " ? (show e))
------------------------------
Message: 4
Date: Sat, 24 Sep 2011 19:52:49 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Question regarding to type classes
To: [email protected]
Cc: Johannes Engels <[email protected]>
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Saturday 24 September 2011, 19:21:17, Johannes Engels wrote:
> Dear list members,
>
> as an exercise, I tried to define a type class for structures with
> ordered key values. The key values could be numbers, but also strings.
> For instance, I intend to define an address list containing records with
> names as key values. So far, my type class definition contains a
> function "key", which should extract the key values from the structures,
> and a function which compares the key values. So I tried:
>
> class StructsWithOrderedKeys a where
> -- no default definition for key
> key :: (Ord b) => a -> b
This does not mean what I think you intend.
This type signature means that key can produce any type belonging to Ord,
whatever the caller desires.
So, I need a String, key can produce it, Bool? too, from the same value,
Integer? yes, also that...
>
> (<?) :: a -> a -> Bool
> x <? y = (key x) < (key y)
>
> Here I get the following error message from GHCI:
>
> "Ambiguous type variable 'b' in the constraint:
> 'Ord b' arising from a use of 'key' ...
> Probable fix: add a type signature that fixes these type variable(s)"
>
> Could anybody explain what ambiguity arises here? As the arguments of
> (<?) are of the same type, I expected also the results (key x) and (key
> y) to be of the same type, which should be by the type constraint for
> "key" an instance of Ord. Why I am not allowed to use "key" in the
> definition of (<?) ?
Because, as said above, key's type says it can produce values of different
types from the same argument, so the compiler can't know which type to
pick, should it produce
x <? y = (key x :: Integer) < key y
or
x <? y = (key x :: String) < key y
or ...
So the type at which to do the comparison is ambiguous.
What you probably intended is that for every type s which is an instance of
StructsWithOrderedKeys, there is a type k, belonging to Ord, such that the
function key produces values of type k from values of type s.
You can achieve that by using multiparameter type classes (with functional
dependencies) or associated types.
With associated types, it would be
==========
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
module Structs where
class (Ord (Key a)) => StructsWithOrderedKeys a where
type Key a
key ::a -> Key a
(<?) :: a -> a -> Bool
x <? y = key x < key y
data Pair = P { pkey :: String, pval :: Int } deriving Show
instance StructsWithOrderedKeys Pair where
type Key Pair = String
key = pkey
==========
and with multiparameter type classes
==========
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module Structs where
-- The "| a -> b" is the functional dependency saying that a
-- uniquely determines b
class (Ord b) => StructsWithOrderedKeys a b | a -> b where
key :: a -> b
(<?) :: a -> a -> Bool
x <? y = key x < key y
data Pair = P { pkey :: String, pval :: Int } deriving Show
instance StructsWithOrderedKeys Pair String where
key = pkey
=========
Use what you prefer, some things are easier to express using FunDeps,
others using associated types.
Generally, FunDeps were there first, but people tend to rather use type
families nowadays.
------------------------------
Message: 5
Date: Sat, 24 Sep 2011 14:00:24 -0400
From: Kyle Murphy <[email protected]>
Subject: Re: [Haskell-beginners] how more efficient read/write a file
?
To: Benjamin Edwards <[email protected]>
Cc: Beginners <[email protected]>
Message-ID:
<CA+y6JcxV3DP6L0+moyhW3QNvZ12qZPitoXL6fV8=17yp-73...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
It's not for the faint of heart, but the enumerator package is also supposed
to provide very good performance for stream transformations. I've looked at
it a bit myself but I'm still struggling to wrap my head around the types
involved, which like most things in Haskell is the key to understanding the
whole thing.
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Sat, Sep 24, 2011 at 05:01, Benjamin Edwards <[email protected]>wrote:
> You should look up bytestring and friends on hackage.
>
> If it is something quite simple you can use the lazy variants and provided
> that you don't try to hold onto the input you should get nice constant space
> without trying too hard.
>
> I recommend the early chapters on IO in real world haskell if you want more
> info on lazy IO.
> On 24 Sep 2011 03:06, "anyzhen" <[email protected]> wrote:
> > consider this :
> > i want load a 4G file(or some bigger file) ,and the process data
> operation just like 010 to 101( XOR bits ) , is it some efficient function
> down it ?
> > such hPutStr hPutChar is Char layer , is exist bit layer operations?
> >
> >
> > thanks for any help
> >
> >
> > [email protected]
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110924/917c28e3/attachment-0001.htm>
------------------------------
Message: 6
Date: Sat, 24 Sep 2011 20:12:10 +0200
From: Johannes Engels <[email protected]>
Subject: [Haskell-beginners] Question regarding to type classes
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Thank you very much, Antoine Latter and, particularly, Daniel Fischer
for your excellent explanation! You have exactly understood what I
intended and answered my question completely, so you really made my day!
Johannes
------------------------------
Message: 7
Date: Sat, 24 Sep 2011 21:21:59 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] how to catch the error thrown by
openFile?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="utf-8"
On Saturday 24 September 2011, 19:52:24, Ovidiu Deac wrote:
> Given this function
>
> f :: MyMonad String
> f = do
> liftIO $ putStrLn "Please enter a file name: "
> name ? liftIO getLine
> hFile ? liftIO $ openFile name ReadMode
> content ? liftIO $ hGetContents hFile
> return $ content
>
> I would like to catch the error thrown by openFile and translate it to
> my own exception type.
>
> So first I tried this:
> hFile ? (liftIO $ openFile name ReadMode) `catch` ?_ ? throwError
> (KnownErr "open failed")
catch has type (IO a -> (e -> IO a) -> IO a) [where e = IOError if you're
using Prelude.catch, and e can be any instance of Exception if you're using
Control.Exception.catch (recommended)].
But (liftIO ioAction) has type (MyMonad a), so that can't be used as an
argument to catch.
Nor can (\_ -> throwError (KnownErr "...")).
>
> ..but it fails because the error handler is returning a different type
> then the "try block". Right?
No, it fails because both have the wrong type for catch.
It would typecheck with catchError instead of catch, but that wouldn't
catch the error :(
>
> Then I tried this:
> f = do
> liftIO $ putStrLn "Please enter a file name: "
> name ? liftIO getLine
> hFile ? (liftIO $ openFile name ReadMode ? return.Right)
> `catch` ?_ ? return (Left $ KnownErr "open failed")
Close. If you replace liftIO with ErrorT in that line and move the first
open parenthesis past the $, then it works and does what you want. Without
changing the following two lines (or, better, do change them;
do x <- act
return x
is the same as just
act
). liftIO adds a layer of Either, ErrorT doesn't.
hFile <- ErrorT $ liftM Right (openFile name ReadMode)
`catch` (\_ -> return $ Left (KnownErr "open failed"))
liftIO $ hGetContents hFile
------------------------------
Message: 8
Date: Sun, 25 Sep 2011 01:27:54 +0300
From: Ovidiu Deac <[email protected]>
Subject: [Haskell-beginners] how to catch the error thrown by
openFile?
To: beginners <[email protected]>
Message-ID:
<CAKVsE7tYTybBNd4QhN2V1=sJ8oPFJw6j0YNn=qG0S97JV7z=z...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Thanks a lot! It took me a while to understand what you meant but
eventually I got it.
This is the final version and it looks much better:
f :: MyMonad String
f = do
?liftIO $ putStrLn "Please enter a file name: "
?name ? ?liftIO getLine
?hFile ? ?ErrorT $ (openFile name ReadMode ? return.Right)
? ? ? ? ? ? ? ?`catch` ?_ ? return.Left $ KnownErr "open failed"
?content ? ?liftIO $ hGetContents hFile
?return content
Somehow I understand but I don't have the feeling yet why I apply
ErrorT to the whole catched expression instead of liftIO. Do you have
a nice explanation for it?
Ovidiu
On Sat, Sep 24, 2011 at 10:21 PM, Daniel Fischer
<[email protected]> wrote:
> On Saturday 24 September 2011, 19:52:24, Ovidiu Deac wrote:
>> Given this function
>>
>> f :: MyMonad String
>> f = do
>> ? liftIO $ putStrLn "Please enter a file name: "
>> ? name ? ?liftIO getLine
>> ? hFile ? ?liftIO $ openFile name ReadMode
>> ? content ? ?liftIO $ hGetContents hFile
>> ? return $ content
>>
>> I would like to catch the error thrown by openFile and translate it to
>> my own exception type.
>>
>> So first I tried this:
>> ? hFile ? ?(liftIO $ openFile name ReadMode) `catch` ?_ ? ?throwError
>> (KnownErr "open failed")
>
> catch has type (IO a -> (e -> IO a) -> IO a) [where e = IOError if you're
> using Prelude.catch, and e can be any instance of Exception if you're using
> Control.Exception.catch (recommended)].
>
> But (liftIO ioAction) has type (MyMonad a), so that can't be used as an
> argument to catch.
> Nor can (\_ -> throwError (KnownErr "...")).
>
>>
>> ..but it fails because the error handler is returning a different type
>> then the "try block". Right?
>
> No, it fails because both have the wrong type for catch.
> It would typecheck with catchError instead of catch, but that wouldn't
> catch the error :(
>
>>
>> Then I tried this:
>> f = do
>> ? liftIO $ putStrLn "Please enter a file name: "
>> ? name ? ?liftIO getLine
>> ? hFile ? ?(liftIO $ openFile name ReadMode ? return.Right)
>> ? ? ? ? ? ? ? ? `catch` ?_ ? return (Left $ KnownErr "open failed")
>
> Close. If you replace liftIO with ErrorT in that line and move the first
> open parenthesis past the $, then it works and does what you want. Without
> changing the following two lines (or, better, do change them;
> do x <- act
> ? return x
>
> is the same as just
>
> act
> ). liftIO adds a layer of Either, ErrorT doesn't.
>
> ?hFile <- ErrorT $ liftM Right (openFile name ReadMode)
> ? ? ? `catch` (\_ -> return $ Left (KnownErr "open failed"))
> ?liftIO $ hGetContents hFile
>
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 39, Issue 29
*****************************************