Re: [Haskell-cafe] ghc static linking on Windows

2009-07-02 Thread Thomas ten Cate
You cannot link statically to a .dll file. Either link statically with
the so-called import library (.lib) (there are tools to generate one
from a .dll, I believe), or link statically with a static build of
SQLite, which is also a .lib file.

Hope that helps,

Thomas

On Wed, Jul 1, 2009 at 19:18, GüŸnther Schmidtgue.schm...@web.de wrote:
 Hi,

 I tried to compile an app that uses sqlite3.dll with the -optl-static flag
 and the error message is:

 C:\ghc\ghc-6.10.3\gcc-lib\ld.exe: cannot find -lsqlite3
 collect2: ld returned 1 exit status

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] golf, predicate check function for MonadPlus (was Re: How to read safely?)

2009-07-02 Thread Jon Fairbairn
Dan Doel dan.d...@gmail.com writes:

 There was talk of adding a readMaybe a while ago, but apparently it
 never happened.

 As it is, you can use reads, read s becomes:

 case reads s of
   [(a, rest)] | all isSpace rest - code using a
   _  - error case

 which ensures that you have an unambiguous parse with only trailing
 whitespace. You can, of course, modify that if you don't care about
 ambiguity or trailing characters.

I was wondering about a more algebraic way of writing that; here's a
version (that doesn't care about ambiguity)

readMaybe :: Read a = String - Maybe a
readMaybe
= join . fmap no_trailing_garbage . listToMaybe . reads
  where no_trailing_garbage = fmap fst . check (all isSpace . snd)

check :: (MonadPlus m) = (a - Bool) - a - m a
check p a
| p a = return a
| otherwise = mzero


I tried Hoogling for a function like check, but couldn't find it. Surely
there's one in a library somewhere? It looks useful to me. (I'm rather
taken by way the check (all isSpace . snd) part reads)

Monad.guard comes close but fails to get the cigar; in fact 

guard b == check (const b) ()

So check is more general.


Also, I don't see a singletonListToMaybe that one could use in place of
listToMaybe to require unambiguity. Could do

isSingleton [a] = True
isSingleton _ = False

and then use listToMaybe . join . check isSingleton -- aha! Another
use for check!




 Jón


[Footnote: I thought of writing guard == flip (check . const) () but
then realised it was pointless]

-- 
Jón Fairbairn jon.fairba...@cl.cam.ac.uk

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
1. Learning haskell I discovered that I/O should be avoided nearly 'at
all costs'. The problem is that the IO monad is the only one which have
more interactive work flow. There is Reader/Writer monad but in fact
AFAIU first one is about the environment and second one is about
logging. Implementation of Writer can be defined in terms of handles but
it is rather limited (either non-full implementation which may be
confusing or need of caching the result for pass etc.).

I searched the hackage but I didn't find package with pure I/O. Such
package may look like:

class (Monad m, Monoid v) = MonadInput v m where
-- | Gets an element from input (line of text [with \n], 4096 bytes,
--   or something like that). mzero on end
getChunk :: m v
class (Monad m, Monoid v) = MonadOutput v m where
-- | Puts an element
putChunk :: v - m ()

In similar way filters (for example buffered input) can be defined:
class (MonadInput v m) = MonadBufferedInput m where
-- | If not whole chunk has been consumed at once (for example only
--   first 3 elements from list) rest can be returned. It will be 
--   returned as part of the input on next getChunk call.
returnChunk :: v - m ()
data (MonadInput v m, Monoid v) =
 BufferedInputT v m a = BufferedInputT a v

Also pipes may be defined (as far as I understand but I'm not 100% sure)
which probably will simplify the writing of network tests:

-- | Evaluates the first argument. If the getChunk is called the 
--   evaluation is passed to second argument until the putChunk is 
--   called, which argument is returned in the first argument
callPipeT :: (Monad m, Monoid v) =
 PipeInputT v m a - PipeOutputT v m b - m (a, b)

I've started some tests but I'd be grateful for comments (well -
probably I'm not the first who come to this idea so a) there is such
package or b) my level of Haskell does not allow me to see the
problems).

2. I find writing monad transformers annoying. 
Additionally if package defines transformer A and another transformer B
they need to be connected 'by hand'.

I find a simple solution which probably is incorrect as it hasn't been
used:

instance (MonadState s n, Monad (m n), MonadTrans m) =
 MonadState s (m n) where
get = lift get
put = lift . put

(requires FlexibleInstances MultiParamTypeClasses FlexibleContexts
UndecidableInstances - two last are not extensions used by mtl)

Regards

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Bulat Ziganshin
Hello Maciej,

Thursday, July 2, 2009, 3:31:59 PM, you wrote:

 class (Monad m, Monoid v) = MonadInput v m where
 -- | Gets an element from input (line of text [with \n], 4096 bytes,
 --   or something like that). mzero on end
 getChunk :: m v
 class (Monad m, Monoid v) = MonadOutput v m where
 -- | Puts an element
 putChunk :: v - m ()

how about interact function?

-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Jules Bean

Ross Paterson wrote:

On Wed, Jul 01, 2009 at 10:55:39AM -0700, Bryan O'Sullivan wrote:

Okay, here's a tentative plan that will help to figure out the answer. I'll
build a fiddled base package that rewires the Monoid class to have (++) be the
binary operator, and mappend as a synonym for it. I'll import the Monoid (++)
into the Prelude. I'll see how much breaks. If that much builds smoothly, I'll
see how much of the rest of Hackage builds, both with and without this custom
base package. I'll follow up here with the results, along with a suggestion of
how acceptable I think the observed level of breakage is.


Generalizing (++) will break some Haskell 98 code, e.g.

  append = (++)

I think that's a show-stopper.


I agree it's an issue; and it's the reason I didn't even suggest it 
myself, favouring a new symbol.


I don't think it's a show stopper, in principle. In principle you can 
imagine a -h98 flag which you pass to compilers which choose a strictly 
h98-compliant prelude as opposed to a slightly generalised newer one.


I'm not the person who would have to maintain that arrangement. I guess 
that's a call for the people who would have to do the work. There is 
already a haskell98 package, I think, which is the first step?


Jules
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
On Thu, 2009-07-02 at 15:43 +0400, Bulat Ziganshin wrote:
 Hello Maciej,
 
 Thursday, July 2, 2009, 3:31:59 PM, you wrote:
 
  class (Monad m, Monoid v) = MonadInput v m where
  -- | Gets an element from input (line of text [with \n], 4096 bytes,
  --   or something like that). mzero on end
  getChunk :: m v
  class (Monad m, Monoid v) = MonadOutput v m where
  -- | Puts an element
  putChunk :: v - m ()
 
 how about interact function?
 

Well. As far as I know there is no way of using it with network.
Additionally there is hard to put monadic code in it:

myFunc :: (MonadInput i, MonadOutput o) =
  (String - m a) - MyMonad i o m [a]

If m == IO - which may be a case in normal code it requires
unsafePerformIO with all it's problems. In testing I can use pipes and
Identity simplifying the whole testing - allowing user to use it's own
monads.

The other problem is that the order sometimes matters. Consider:
main = interact (\x - What's your name?\n ++ Hello:\n ++ x)

For human being it is annoying but sometimes it is for example against
RFC.

Regards 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Fun with type functions

2009-07-02 Thread Simon Peyton-Jones
Friends

Ken, Oleg, and I have finished Version 2 of our paper Fun with Type 
Functions, which gives a programmer's tour of what type functions are and how 
they are useful.

http://haskell.org/haskellwiki/Simonpj/Talk:FunWithTypeFuns

If you have a moment to look at, and wanted to help us improve it, the above 
link goes to a wiki page where you can comment on the paper or discuss it.  We 
still have time to improve it.

Thanks

Simon
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Monoid wants a (++) equivalent

2009-07-02 Thread Heinrich Apfelmus
Ross Paterson wrote:
 On Wed, Jul 01, 2009 at 04:53:05PM +0200, Thomas Davie wrote:
 On 1 Jul 2009, at 16:46, Edward Kmett wrote:

 I'm rather fond of the () suggestion, but would be happy with  
 anything better than mappend! ;)
 I find it rather ugly, it has a lot of connotations of does not equals 
 from other languages.
 
 Forget Pascal: think of it as a diamond.

I too like shiny diamonds, as exemplified in

  http://apfelmus.nfshost.com/monoid-fingertree.html



Regards,
apfelmus

--
http://apfelmus.nfshost.com

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] A Strict GCL Interpreter in Haskell

2009-07-02 Thread Hector Guilarte
Hi everyone!

(First of all, I don't know Monads!)

I made a GCL (Guarded Command Language) Compiler and Interpreter for my
Languages and Machines course in my University with alex, happy and ghc. I
still have a doubt:

1) Since Haskell is Lazy, and my GCL program is being interpreted in Haskell
then my GCL is Lazy too (I know is not as simple as that but believe me,
somehow it is behaving lazy). The problem is that it can't be lazy (said to
me by my teacher on monday) so I tried using seq, but it didn't work, I'll
paste the code after this:
Programs in GCL like:
a)
var i : value
main
i - 1 / 0
end

b)
var i : value
main
i - 1 / 0;
show i
end

c)
var i : value
var foo : array of 2
main
i - foo[42]
end

d)
var i : value
var foo : array of 2
main
i - foo[42];
show i
end

act like this:
a and c finish interpretation
b throws division by zero error and finish interpretation
d throws index out of bounds error and finish interpretation

Now the code:
(it is in Spanish. ListLValue is a List of L-Values for the assigments,
ListExpr is the list of Expressions to be assigned, Tabla is the Symbol
Table (Data.Map), actualizarVar updates a Variable in the Symbol Table with
the new value valor, ActualizarArray updates the position indice of an
array in the Symbol Table. evalExpr evaluates an arithmetic Expression and
returns an Int. Inside evalExpr are the verifications for division by zero
of modulo by zero.)

evalAsignacion:: ListLvalue - ListExpr - Tabla - Tabla
evalAsignacion [] [] tabla = tabla
evalAsignacion ((Lid id):valueList) (expr:exprList) tabla =
let valor = (evalExpr expr tabla)
in valor `seq` evalAsignacion valueList exprList (actualizarVar id valor
tabla)
evalAsignacion ((LArrayPosition id exprArray):valueList) (expr:exprList)
tabla =
let valor = (evalExpr expr tabla)
indice = (evalExpr exprArray tabla)
in valor `seq` indice `seq` evalAsignacion valueList exprList
(actualizarArray id indice valor tabla)

evalExpr:: Expr - Tabla - Int
evalExpr expr tabla =
let salida = (snd (evalAritmetico expr tabla))
in salida `seq` if (isLeft salida) then error (getLeft salida)
  else getRight salida

--((Int,Int) is the Line and Colum, that's for error reporting)
evalAritmetico :: Expr - Tabla - ((Int,Int),(Either String Int))
--LET ME KNOW IF YOU NEED THIS PART TOO


Thanks in advance,

Hector Guilarte
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Alexander Dunlap
On Wed, Jul 1, 2009 at 11:26 AM, Ross Patersonr...@soi.city.ac.uk wrote:
 On Wed, Jul 01, 2009 at 10:55:39AM -0700, Bryan O'Sullivan wrote:
 Okay, here's a tentative plan that will help to figure out the answer. I'll
 build a fiddled base package that rewires the Monoid class to have (++) be 
 the
 binary operator, and mappend as a synonym for it. I'll import the Monoid (++)
 into the Prelude. I'll see how much breaks. If that much builds smoothly, 
 I'll
 see how much of the rest of Hackage builds, both with and without this custom
 base package. I'll follow up here with the results, along with a suggestion 
 of
 how acceptable I think the observed level of breakage is.

 Generalizing (++) will break some Haskell 98 code, e.g.

  append = (++)

 I think that's a show-stopper.
 ___

Could we use some default rules to keep H98 code working? I don't know
much about defaulting, but

times = (*)

works fine and defaults to type Integer. Could we not do the same
thing with monoids, having monoids default to type []?

Alex
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] [ghc] kind of the function arrow

2009-07-02 Thread Dominic Orchard
I was just playing around and noticed that the kind of the function 
arrow in GHC is (?? - ? - *) when I (naively) expected it to be (* - 
* - *).
After looking at 
(http://hackage.haskell.org/packages/archive/ghc/6.10.2/doc/html/Type.html#5) 
I see that the kind of (-) means that the parameter type cannot be an 
unboxed tuple, whilst the result type can be anything. Why is this?

After reading this documentation I would expect the kind (? - ? - *).

I'm now wondering if the kind of (-) could cause problems if the 
following style of declaration is requried:


 type FunArg a b = (a - b, a)

*Main :k FunArg
FunArg :: * - * - *

By using type variables, whose default kind is *, the function type is 
fixed to use only boxed types. But if one wanted to allow unboxed type 
parameters the kind would be wrong, and an explicit kind signature of # 
or ? can't be given as they are not part of Haskell's source language.


I guess my question is why the (?? - ? - *) kind on (-) and what to 
do if synonyms or data types over (-) are required such as the example 
just stated. I'm just curious.


Thanks,
Dominic
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Alexander Dunlap
On Wed, Jul 1, 2009 at 10:11 PM, David Menendezd...@zednenem.com wrote:
 In Wed, Jul 1, 2009 at 3:38 PM, Thomas Schillingnomin...@googlemail.com 
 wrote:
 2009/7/1 David Leimbach leim...@gmail.com
 Just because the compiler can figure out what I mean because it has a great
 type system, I might not be able to figure out what I mean a year from now
 if I see ++ everywhere.

 Yep, had the same experience.  On the one hand, using monoids lets you
 delay some design decisions for later and lets you reuse more library
 code.  On the other hand, it sometimes makes it really hard to see
 what the code is actually doing--especially if you use more than one
 monoid.

 For this reason on of the first advanced features I implemented in the
 (yet unreleased) scion IDE library allows you to look up the
 instantiated type of an identifier.  Unfortunately, jumping to the
 definition (or documentation) of the monoid instance is a bit more
 difficult.  Haddock should allow documentation on instance
 declarations...

 I disagree. The solution is to not create instances when it isn't
 obvious what the instance does. That's why we have Sum and Prod in
 Data.Monoid instead of declaring instances directly for Int.

 With Monoid, I'd go further and say that you should not use mempty and
 mappend unless you are writing polymorphic code. If you are writing to
 a specific monoid instance, you should use a specific function.

 --
 Dave Menendez d...@zednenem.com
 http://www.eyrie.org/~zednenem/
 ___

I tend to disagree. I think that Haskell has seen a lot of syntax
bloat in the interest of monomorphism. We have List.append, Map.union,
Set.union, Sequence., etc., all with different notation, even though
these all denote the same operation: taking two of (whatever) and
combining them into one. With mappend, you know exactly what the
function is supposed to do: combine two things together, and it
doesn't matter what datatypes you're using, because that's always what
it means.

Alex
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Ross Paterson
On Thu, Jul 02, 2009 at 12:46:37PM +0100, Jules Bean wrote:
 I'm not the person who would have to maintain that arrangement. I guess  
 that's a call for the people who would have to do the work. There is  
 already a haskell98 package, I think, which is the first step?

The Prelude is in the base package.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Monoid wants a (++) equivalent

2009-07-02 Thread Maciej Piechotka
Ketil Malde ketil at malde.org writes:

 
 You know, this might be the right time to start expanding our
 vocabulary beyond seven bits.  Since we're likely to keep mappend
 around as an alias for some time, people would have a grace period to
 adjust. 
 
 How about U+2295 (circle with plus inside it)?
 
 Or, if we would like to stick to the 8-bit subset to keep those 8859-1
 users happy, how about ¤ (funny circle over an x, U+00A4)
 
 -k

I can work with any symbols as long as they are easily typeable. ++ is 3 easy
key press. `mappend` is 9. In both cases I don't need to look on keyboard as I
know exactly where they are. However there is no way I can remember where U+00A4
is - probably it is not on all keyboards (reversing  and @ gives me a lot of
problems in UK keyboards. FR keyboards was nightmare just because a few keys
where at different place). In fact I'd need to open keyboard mapping and search
for symbol. A lot of trouble just for single symbol.

To summarise - It doesn't matter is symbol is or isn't in ASCII or ISO 8859-1 as
long as it can be produced easily.

Regards

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Monoid wants a (++) equivalent

2009-07-02 Thread Johan Tibell
On Thu, Jul 2, 2009 at 6:45 PM, Maciej Piechotka uzytkown...@gmail.comwrote:

 I can work with any symbols as long as they are easily typeable. ++ is 3
 easy
 key press. `mappend` is 9. In both cases I don't need to look on keyboard
 as I
 know exactly where they are. However there is no way I can remember where
 U+00A4
 is - probably it is not on all keyboards (reversing  and @ gives me a lot
 of
 problems in UK keyboards. FR keyboards was nightmare just because a few
 keys
 where at different place). In fact I'd need to open keyboard mapping and
 search
 for symbol. A lot of trouble just for single symbol.

 To summarise - It doesn't matter is symbol is or isn't in ASCII or ISO
 8859-1 as
 long as it can be produced easily.


I would like for my font to have a glyph for it as well so my code doesn't
look like tofu.

-- Johan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Strict GCL Interpreter in Haskell

2009-07-02 Thread Daniel Fischer
Am Donnerstag 02 Juli 2009 18:35:17 schrieb Hector Guilarte:
 Hi everyone!

 (First of all, I don't know Monads!)

 I made a GCL (Guarded Command Language) Compiler and Interpreter for my
 Languages and Machines course in my University with alex, happy and ghc. I
 still have a doubt:

 1) Since Haskell is Lazy, and my GCL program is being interpreted in
 Haskell then my GCL is Lazy too (I know is not as simple as that but
 believe me, somehow it is behaving lazy). The problem is that it can't be
 lazy (said to me by my teacher on monday) so I tried using seq, but it
 didn't work, I'll paste the code after this:
 Programs in GCL like:
 a)
 var i : value
 main
 i - 1 / 0
 end

 b)
 var i : value
 main
 i - 1 / 0;
 show i
 end

 c)
 var i : value
 var foo : array of 2
 main
 i - foo[42]
 end

 d)
 var i : value
 var foo : array of 2
 main
 i - foo[42];
 show i
 end

 act like this:
 a and c finish interpretation
 b throws division by zero error and finish interpretation
 d throws index out of bounds error and finish interpretation

Sorry, I don't quite get that. Do you mean that in your interpreter a) and c) 
run to 
completion without raising an error, although they should raise an error and 
terminate 
upon that?
And b) and d) raise their respective error as they should?
Or what is the expected behaviour and what is the actual behaviour?


 Now the code:
 (it is in Spanish. ListLValue is a List of L-Values for the assigments,
 ListExpr is the list of Expressions to be assigned, Tabla is the Symbol
 Table (Data.Map), actualizarVar updates a Variable in the Symbol Table with
 the new value valor, ActualizarArray updates the position indice of an
 array in the Symbol Table. evalExpr evaluates an arithmetic Expression and
 returns an Int. Inside evalExpr are the verifications for division by zero
 of modulo by zero.)

 evalAsignacion:: ListLvalue - ListExpr - Tabla - Tabla
 evalAsignacion [] [] tabla = tabla
 evalAsignacion ((Lid id):valueList) (expr:exprList) tabla =
 let valor = (evalExpr expr tabla)
 in valor `seq` evalAsignacion valueList exprList (actualizarVar id
 valor tabla)
 evalAsignacion ((LArrayPosition id exprArray):valueList) (expr:exprList)
 tabla =
 let valor = (evalExpr expr tabla)
 indice = (evalExpr exprArray tabla)
 in valor `seq` indice `seq` evalAsignacion valueList exprList
 (actualizarArray id indice valor tabla)

 evalExpr:: Expr - Tabla - Int
 evalExpr expr tabla =
 let salida = (snd (evalAritmetico expr tabla))
 in salida `seq` if (isLeft salida) then error (getLeft salida)
   else getRight salida

 --((Int,Int) is the Line and Colum, that's for error reporting)
 evalAritmetico :: Expr - Tabla - ((Int,Int),(Either String Int))
 --LET ME KNOW IF YOU NEED THIS PART TOO


 Thanks in advance,

 Hector Guilarte

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Edward Kmett
 Wed, Jul 1, 2009 at 4:17 PM, Raynor Vliegendhart shinnon...@gmail.comwrote:

 We could use (Control.Category..) as an operator, but this would
 require an additional wrapping layer if we wish to use the existing
 Monoid instances:

  import Prelude hiding (id, (.))
  import Control.Category
  import Data.Monoid
 
  -- Category wrapper for existing Monoid instances
  newtype MonoidC m a b = MonoidC {unwrapMC :: m} deriving (Show)
 
  instance Monoid m = Category (MonoidC m) where
  id = MonoidC mempty
  MonoidC m . MonoidC n = MonoidC $ m `mappend` n

 Furthermore, writing Category instances for monoids require dummy type
 parameters:

  -- Example instance
  newtype SumC m a b = SumC {getSumC :: m} deriving (Show, Eq)
 
  instance Num a = Category (SumC a) where
  id = SumC (fromIntegral 0)
  SumC x . SumC y = SumC $ x + y

I have a monoid-as-category and category-endomorphism as monoid in:
http://comonad.com/haskell/monoids/dist/doc/html/monoids/Data-Monoid-Categorical.html

but there are issues.

1.)  these completely change the typing involved
2.) the monoid as category-with-one-object is pretty scary to someone
without a category theory background.
3.) This doesn't properly represent the category-with-one-object because at
best the two phantom types yield you something like a category like Hask,
which has been fully connected * M where M is the category of your monoid.
Even if you use GADTs to cut down the phantom types to one where the head
and tail of the arrow are the same object and |.| takes a category to its
discrete category (discarding all non-identity arrows) you are looking at a
category like |Hask| * M because of the phantom type.

data CMonoid m n o where
M :: Monoid m = m - CMonoid m a a

instance Monoid m = Category (CMonoid m) where
id = M mempty
M a . M b = M (a `mappend` b)

 Attempting to go any further and railroad that type to equal m fails when
you go to define id. So the categorical notion of a monoid is pretty much a
non-starter in Haskell.

 -Edward Kmett

On
Another disadvantage of this approach is that we cannot have a default
monoid instance for lists (kind mismatch).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] golf, predicate check function for MonadPlus (was Re: How to read safely?)

2009-07-02 Thread Alexander Dunlap
On Thu, Jul 2, 2009 at 3:36 AM, Jon Fairbairnjon.fairba...@cl.cam.ac.uk wrote:
 Dan Doel dan.d...@gmail.com writes:

 There was talk of adding a readMaybe a while ago, but apparently it
 never happened.

 As it is, you can use reads, read s becomes:

     case reads s of
       [(a, rest)] | all isSpace rest - code using a
       _                              - error case

 which ensures that you have an unambiguous parse with only trailing
 whitespace. You can, of course, modify that if you don't care about
 ambiguity or trailing characters.

 I was wondering about a more algebraic way of writing that; here's a
 version (that doesn't care about ambiguity)

 readMaybe :: Read a = String - Maybe a
 readMaybe
    = join . fmap no_trailing_garbage . listToMaybe . reads
      where no_trailing_garbage = fmap fst . check (all isSpace . snd)

 check :: (MonadPlus m) = (a - Bool) - a - m a
 check p a
    | p a = return a
    | otherwise = mzero


 I tried Hoogling for a function like check, but couldn't find it. Surely
 there's one in a library somewhere? It looks useful to me. (I'm rather
 taken by way the check (all isSpace . snd) part reads)

 Monad.guard comes close but fails to get the cigar; in fact

 guard b == check (const b) ()

 So check is more general.


 Also, I don't see a singletonListToMaybe that one could use in place of
 listToMaybe to require unambiguity. Could do

 isSingleton [a] = True
 isSingleton _ = False

 and then use listToMaybe . join . check isSingleton -- aha! Another
 use for check!




  Jón


 [Footnote: I thought of writing guard == flip (check . const) () but
 then realised it was pointless]

 --
 Jón Fairbairn                                 jon.fairba...@cl.cam.ac.uk


You can use the Kleisli composition operator (=) to make it a little nicer.

singletonListToMaybe :: [a] - Maybe a
singletonListToMaybe [x] = Just x
singletonListToMaybe _ = Nothing

check :: MonadPlus m = (a - Bool) - a - m a
check p a
  | p a = return a
  | otherwise = mzero

readMaybe = fmap fst.check (all isSpace.snd) = singletonListToMaybe.reads

Alex
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Luke Palmer
On Thu, Jul 2, 2009 at 5:31 AM, Maciej Piechotka uzytkown...@gmail.comwrote:

 2. I find writing monad transformers annoying.
 Additionally if package defines transformer A and another transformer B
 they need to be connected 'by hand'.


You have not given any concrete problems or examples, so it's hard for me to
comment.  But at first glance, I would conjecture that you are relying too
heavily on monads and sequential thinking.

Consider what your code would look like without a single monad.  Obviously
you cannot talk to the network without IO, but your program can still be *
modeled* purely, and then toss in IO at the last second to tie it to the
network.  This model may be difficult for you because it requires your brain
to be rewired; feel free to mail this list with concrete modeling problems
and we will help you out.

As for the pure model, throw away Reader, Writer, State -- everything, and
just use pure functions.  Then add monads back in *at small scopes* when
they clean things up.

I used to approach problems by designing a monad for my whole program, using
an appropriate stack of transformers.  I suspect such an approach led to the
claim that monads are not appropriate for large software systems in a
popular paper a few months ago.  As I have gained more experience, I found
that this is the *wrong* way to go about using them.  Now my primary use of
monads is within the scope of a single function, to tie together the helper
functions in the where clause.

Luke



 I find a simple solution which probably is incorrect as it hasn't been
 used:

 instance (MonadState s n, Monad (m n), MonadTrans m) =
 MonadState s (m n) where
get = lift get
put = lift . put

 (requires FlexibleInstances MultiParamTypeClasses FlexibleContexts
 UndecidableInstances - two last are not extensions used by mtl)

 Regards

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Jason Dagit
On Thu, Jul 2, 2009 at 1:18 PM, Luke Palmer lrpal...@gmail.com wrote:



 I used to approach problems by designing a monad for my whole program,
 using an appropriate stack of transformers.  I suspect such an approach led
 to the claim that monads are not appropriate for large software systems in
 a popular paper a few months ago.


Link please!  I googled but I couldn't find it :(  I'd like to find out what
you and the authors have learned about the inappropriateness of monads for
large software systems.


Thanks,
Jason
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Bulat Ziganshin
Hello Luke,

Friday, July 3, 2009, 12:18:21 AM, you wrote:

 I used to approach problems by designing a monad for my whole
 program, using an appropriate stack of transformers.  I suspect such
 an approach led to the claim that monads are not appropriate for
 large software systems in a popular paper a few months ago.  As I
 have gained more experience, I found that this is the wrong way to
 go about using them. 

was it ghc authors paper? :)

-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ORM for haskell?

2009-07-02 Thread Mads Lindstrøm
Hi Marc Weber

 Hi Mads!
 
 On Tue, Jun 30, 2009 at 11:49:40PM +0200, Mads Lindstrøm wrote:
  Hi Marc Weber
  
   Another example: Updating the age of a pupil:
   
 row = SELECT * FROM pupils where age = 13;
 UPDATE pupils SET age = 14 WHERE id = the id you got above
   
 p = session.query(Pupil).filter(Pupil.age==13).one().age=14
 session.commit()
   
 difference?
 You don't have to care about ids. you just assign a new value and
   tell
 the engine that it should commit.
 So again less chances to get something wrong.
   
  
  Could you not do in SQL:
  
  UPDATE pupils SET age = 14 WHERE age = 13
 Of course.
 But: you can pass around that pupil object to another function and still 
 assign a new age
 then run session.commit().
 When passing around the pupile you can follow the relation_ships
 (relations?) back to school.
 
 def doSomething(pupil):
   pupil['age'] = 13
   pupil.teacher.school.rating += 1
 
 doSomething(session.query(Pupil).filter(Pupil.age==13))
 session.commit()
 
 Now how would you do this using SQL?

As far as I know, you cannot. And it is very nice.

On the other hand you sometimes want to execute more of the logic on the
DBMS, as it leads to better performance. But maybe we can somehow have
our cake and eat it too. E.g. if the user still have some control about
where the logic is executed.

 
 Sorry about the confustion (relation / relation-ship). I mixed up the 
 terminology.
 Anyway I guess you can see here how powerful an ORM can be and why
 we should write such a library for haskell.

Don't be sorry about that. I know people often confuse the terms and I
could have replied just asking if you had not swapped the two terms. In
my native language relation can mean both relation and to relationship.
Guess, it is the same in other languages...

 
 I think it's very hard to invent such a short synax in haskell cause
 you have to take monads into account etc..
 
 And it matters how much time you have to spend writing code.

Yes and yes. I think (my gut tells me so) you will need to use Template
Haskell, if you want something as succinct as the Python code you
showed. Or maybe if you give up type safety, but I guess your are not
willing to do that. But it could be fun (and challenging) coming up with
something really nice.

 
 Thanks for your feedback. I hope there will be some more.
 
 Marc Weber

I may have sounded a bit negative in my previous mails. But I really can
see something cool about what you describe. That said, I think people
are sometimes too eager to replace SQL.

As you properly are already aware, SQL+Relational databases has some
very nice properties (list below is form the top of my head, there are
other advantages):

* They are accessed with a declarative language (SQL)

* They can make high-level optimization automatically and guided by the
user

* They can, transparently, execute queries/updates using multiple
servers/CPUs. It may require some changes to the database, but it can be
done without changing your SQL

* They are based on a nice theoretical foundation

* If databases are normalized properly, data are a lot more transparent
than other ways of organizing data. At least other ways I have seen.

* Normalization provides a lot less ambiguous guidance, than other
development methodologies.

* Transaction support

But as you point out yourself, everything is not rosy. And in addition
to what you write, all the (un)marshaling you need when accessing
databases from Haskell is quite cumbersome.

And I realize that you are not trying to replace RDBs, just building a
nicer interface to them. I am just concerned that some of the nice
properties are lost in the process. I think my main concern comes from
seeing people create databases, by automatically generating tables from
OO-classes. They invariably ends up with something not nearly as nice,
as if they had constructed the database in a more traditional fashion.

To summarize, what you propose is cool. Just do not throw the baby out
with the bathwater.


Greetings,

Mads Lindstrøm




signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
On Thu, 2009-07-02 at 14:18 -0600, Luke Palmer wrote:
 On Thu, Jul 2, 2009 at 5:31 AM, Maciej Piechotka
 uzytkown...@gmail.com wrote:
 2. I find writing monad transformers annoying.
 Additionally if package defines transformer A and another
 transformer B
 they need to be connected 'by hand'.
 
 You have not given any concrete problems or examples, so it's hard for
 me to comment.  But at first glance, I would conjecture that you are
 relying too heavily on monads and sequential thinking.
 
 Consider what your code would look like without a single monad.
 Obviously you cannot talk to the network without IO, but your program
 can still be modeled purely, and then toss in IO at the last second to
 tie it to the network.  This model may be difficult for you because it
 requires your brain to be rewired; feel free to mail this list with
 concrete modeling problems and we will help you out.
 
 As for the pure model, throw away Reader, Writer, State -- everything,
 and just use pure functions.  Then add monads back in at small scopes
 when they clean things up. 
 

AFAIU you comment the 2de point only. I look at this moment from
library, not program point of view.

So consider the library IOMonad which defined some MonadInput v m monad.
Then you have NNTP library which has NntpT m monad.

Each of them defines appropriate stack such as that NntpT (State s) is
instance of MonadState. But if there is NntpT MyInput, where MyInput
isinstance of MonadInput, is not MonadInput. To do it with current
approach the libraries would have to be interlinked.

Also it is quite boring to include for all monad
instance ... = ... where
f1 = lift f1
f2 = lift f2
...

 I used to approach problems by designing a monad for my whole program,
 using an appropriate stack of transformers.

I thought about others which might have want to use my monads in their
functions...

 I suspect such an approach led to the claim that monads are not
 appropriate for large software systems in a popular paper a few
 months ago.

I'd appreciate the link - google find nothing. I fall in love in Haskell
about a week or two ago and I fall in love just after I started learning
it ;)

 As I have gained more experience, I found that this is the wrong way
 to go about using them.  Now my primary use of monads is within the
 scope of a single function, to tie together the helper functions in
 the where clause.
 
 Luke
 

Regards

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Gwern Branwen
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

On Thu, Jul 2, 2009 at 5:05 PM, Maciej Piechotka wrote:
 I'd appreciate the link - google find nothing. I fall in love in Haskell
 about a week or two ago and I fall in love just after I started learning
 it ;)

Research programming languages like Haskell [22] and ML [20] didn't
seem to offer any near-term solution. Diatchki's work on fine-grain
representation in Haskell [25] is not yet main-stream, and had not yet
started when we began work on BitC. Support for state in Haskell
exists in the form of the I/O monad [23], but in our opinion the
monadic idiom does not scale well to large, complexly stateful
programs,1  and imposes constraints that are unnatural in the eyes of
systems programmers.

Oh, and not only do our monads not scale, they're slow to boot:

 Ultimately, the problem with Haskell and ML for our purposes is that
the brightest and most aggressive programmers in those languages,
using the most aggressive optimization techniques known to the
research community, remain unable to write systems codes that compete
reasonably with C or C++. The most successful attempt to date is
probably the FoxNet TCP/IP protocol stack, which incurred a 10x
increase in system load and a 40x penalty in accessing external memory
relative to a conventional (and less aggressively optimized) C
implemenation. [ 4 ,6  ]

http://www.bitc-lang.org/docs/bitc/bitc-origins.html

- --
gwern
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAkpNJWoACgkQvpDo5Pfl1oLpeQCcDXUnfBaitwii3rhortVqO8Fr
SXIAnAiKY5EGg/ssZHOaooP1ag1xGIE4
=iugB
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Strict GCL Interpreter in Haskell

2009-07-02 Thread Tillmann Rendel

Hi Hector,

Hector Guilarte wrote:

1) Since Haskell is Lazy, and my GCL program is being interpreted in Haskell
then my GCL is Lazy too (I know is not as simple as that but believe me,
somehow it is behaving lazy). The problem is that it can't be lazy (said to
me by my teacher on monday).



evalExpr:: Expr - Tabla - Int
evalExpr expr tabla =
let salida = (snd (evalAritmetico expr tabla))
in salida `seq` if (isLeft salida) then error (getLeft salida)
  else getRight salida


I think the problem with your code is that you call error, instead of 
reporting the error back to the caller. evalExpr can go wrong (consider 
5 / 0), but this fact is not represented in the type:


  evalExpr:: Expr - Tabla - Int

The type says that for all expressions and all symbol tables, you can 
produce an int result. But that is not true! So try using this more 
adequate type:


  evalExpr :: Expr - Tabla - Either String Int

Now, for all expressions and symbol tables, evalExpr either can compute 
an integer result, or it informs you that something went wrong. If you 
have these kinds of types on all your functions, your main program 
becomes something like:


  main = do
code - readAndParseFile somefile
case evalProgram code of
  Left error - putStrLn (Error:  ++ error)
  Right () - putStrLn Worked fine!

So if you need fine-grained control over error-handling, add explicit 
error handling, and do not use the error function.


Good luck!

  Tillmann
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Flipping *-*-* kinds, or monadic finally-tagless madness

2009-07-02 Thread Kim-Ee Yeoh

I'm trying to write HOAS Show instances for the finally-tagless
type-classes using actual State monads.  

The original code:
http://okmij.org/ftp/Computation/FLOLAC/EvalTaglessF.hs

Two type variables are needed: one to vary over the Symantics 
class (but only as a phantom type) and another to vary over the 
Monad class. Hence, the use of 2-variable type constructors.

 type VarCount = int
 newtype Y b a = Y {unY :: VarCount - (b, VarCount)}

Not knowing of a type-level 'flip', I resort to newtype isomorphisms:

 newtype Z a b = Z {unZ :: Y b a}
 instance Monad (Z a)  where
return x = Z $ Y $ \c  - (x,c)
(Z (Y m)) = f  = Z $ Y $ \c0 - let (x,c1) = m c0 in (unY . unZ) (f
 x) c1-- Pace, too-strict puritans
 instance MonadState String (Z a)  where
get   = Z $ Y $ \c - (show c, c)
put x = Z $ Y $ \_ - ((), read x)

So far so good.  Now for the Symantics instances (abridged).

 class Symantics repr  where
int  :: Int  - repr Int  -- int literal
add :: repr Int  - repr Int - repr Int
lam :: (repr a - repr b) - repr (a-b)

 instance Symantics (Y String)  where
int = unZ . return . show
add x y = unZ $ do
   sx - Z x
   sy - Z y
   return $ ( ++ sx ++  +  ++ sy ++ )

The add function illustrates the kind of do-sugaring we know and love
that I want to use for Symantics.

lam f   = unZ $ do
   show_c0 - get
   let
  vname = v ++ show_c0
  c0 = read show_c0 :: VarCount
  c1 = succ c0
  fz :: Z a String - Z b String
  fz = Z . f . unZ
   put (show c1)
   s - (fz . return) vname
   return $ (\\ ++ vname ++  -  ++ s ++ )

Now with lam, I get this cryptic error message (under 6.8.2):

Occurs check: cannot construct the infinite type: b = a - b
When trying to generalise the type inferred for `lam'
  Signature type: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
b1)
  Type to generalise: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
b1)
In the instance declaration for `Symantics (Y String)'

Both the two types in the error message are identical, which suggests
no generalization is needed.  I'm puzzled why ghc sees an infinite type.

Any ideas on how to proceed?

-- 
View this message in context: 
http://www.nabble.com/Flipping-*-%3E*-%3E*-kinds%2C-or-monadic-finally-tagless-madness-tp24314553p24314553.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-07-02 Thread wren ng thornton

Brandon S. Allbery KF8NH wrote:
Some Haskell 
programmers use fmap (because most Monads are also Functors), others use 
liftM.  Both have the same effect:  given a monadic computation m a, 
liftM f turns f into a function that operates on the enclosed a 
instead of the entire m a.


That is, given the theory behind it all, every monad is a functor (note 
the lower case); from which it follows that liftM == fmap. For 
historical reasons the Monad typeclass does not require a Functor 
instance, however, and so it's not the case that every Monad is also a 
Functor (note the upper case).


The function liftM can be defined generically given definitions for 
return and (=), so some prefer to use liftM to avoid the extra Functor 
dependency. The function fmap can be given specialized definitions due 
to overloading, so others prefer to use it for efficiency reasons. The 
($) function is just a symbolic name for fmap.



You'll also see the Applicative typeclass for applicative functors. 
Applicative does require a Functor instance, which is good. (And 
actually, every monad is an applicative functor; though the Monad class 
doesn't require Applicative either.) The function liftA can be defined 
generically given definitions for pure and (*), and liftA == fmap as 
well. The only reason anyone should use liftA is for defining a Functor 
instance when they're too lazy to give a specialized implementation.



--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ORM for haskell?

2009-07-02 Thread Marc Weber
 And I realize that you are not trying to replace RDBs, just building a
 nicer interface to them. I am just concerned that some of the nice
 properties are lost in the process. I think my main concern comes from
 seeing people create databases, by automatically generating tables from
 OO-classes. They invariably ends up with something not nearly as nice,
 as if they had constructed the database in a more traditional fashion.
 
 To summarize, what you propose is cool. Just do not throw the baby out
 with the bathwater.

Hi Mad.

Maybe I want to replace a RDBMS. But this will cost.
You can fire arbitrary SQL statements in no time at RDBMS. You can't do
things like that that easy using a haskell (in memory) only solutions.
So SQL wins here at the moment if you want to be productive.

If you read the .pdf I posted you saw that SQLAlchemy is that coold that
a) you can use the shortcut style and define objects and tables at the
  same time but you als can
b) define both layers independent of each other.

And: Most applications today don't have to scale to an extend forcing
you to move all logic into a database system. If you can one request a
sec on a web application .. That's already very much for most small shop
system. (I'm not talking about Amazon or ebay or such!) I'm talking
about customers who want some more customizations as you can do with
oscommerce.

My main purpose was to see wether someone else would be interested in
spending more effort into such a solution.

Anyway I have still have to do some other work before I can jump into
such a project.

And Mad, I think you already know that RDBMS are not the best solution
because it's very hard to ask a RDBMS wether a query retuns a nullable
value or not. And that makes a huge difference wether you have to use a 
unsafeFromNull like function all the time or not.

Time will tell how much energy I can spend on such this topic in the
future.

cu all
Marc Weber
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monoid wants a (++) equivalent

2009-07-02 Thread Richard O'Keefe

It is claimed that making ++ become another name for the
Monoid mappend operation will break some Haskell 98 code
such as

append = (++)

That example can easily be fixed by adding a type signature, no?

append :: [a] - [a] - [a]
append = (++)

In ghci, at any rate, using mappend instead of (++),
the first is rejected, but the sceond works perfectly.

The nice thing about this is that the code _with_ the type
signature is perfectly legal Haskell 98, so the fix leaves
you with something that works with either reading of (++).

Do we have any other uses of ++ that would be hard to fix
by adding a type signature?


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Strict GCL Interpreter in Haskell

2009-07-02 Thread Tillmann Rendel

Hi Hector,

Hector Guilarte wrote:

I did that already, but it didn't work... Also, since this kind of error would 
be a run time error in my GCL Language, I don't want it to continue executing 
whenever an error is found, that's why I changed it back to just:
evalExpr:: Expr - Tabla - Int

Instead of using the Either String Int...


I think you misunderstand something.

If you use (Expr - Table - Int), you are announcing:
Whatever happens, I keep executing.

If you use (Expr - Table - Either String Int), you are announcing:
I may stop earlier because of some problem.

Since may you want to stop earlier, you should use the second type.


Let's look at a very small example, an interpreter for the following 
little language:


  data Expression
= Literal Integer
| Add Expression Expression
| Divide Expression Expression

Because of division by zero, an interpreter for this language may fail. 
So we have two kinds of return values: Sometimes we return a number, and 
sometimes we return an DivideByZero error. We can reflect that in a 
datatype:


  data Result
= Number Integer
| DivideByZeroError

Now we can write our interpreter:

  eval :: Expression - Result
  eval (Literal n)
= Number n

  eval (Add a b)
= case eval a of
Number result_of_a
  - case b of
   Number result_of_b
 - Number (result_of_a + result_of_b)

   DivideByZeroError
 - DivideByZeroError

DivideByZeroError
  - DivideByZeroError


  eval (Add a b)
= case eval a of
Number result_of_a
  - case b of
   Number result_of_b
 - if b == 0
  then DivideByZeroError
  else Number (result_of_a + result_of_b)

   DivideByZeroError
 - DivideByZeroError

DivideByZeroError
  - DivideByZeroError


This interpreter will stop as soon as it encounters a division by zero, 
because we take care to return DivideByZeroError whenever we see a 
DivideByZeroError in one of the subterms.


So you have to use an appropriate return type (like (Either String Int) 
or Result), and you have to pattern match on the result of earlier 
parts of your program, and propagate the error.


  Tillmann
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Network.CGI -- practical web programming example.

2009-07-02 Thread Brandon S. Allbery KF8NH

On Jul 2, 2009, at 17:59 , wren ng thornton wrote:

Brandon S. Allbery KF8NH wrote:
Some Haskell programmers use fmap (because most Monads are also  
Functors), others use liftM.  Both have the same effect:  given a  
monadic computation m a, liftM f turns f into a function that  
operates on the enclosed a instead of the entire m a.


That is, given the theory behind it all, every monad is a functor  
(note the lower case); from


Yeh, I decided to bypass the whole all monads are functors, but for  
Hysterical Raisins not all Monads are Functors morass.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Flipping *-*-* kinds, or monadic finally-tagless madness

2009-07-02 Thread Ahn, Ki Yung

Kim-Ee Yeoh wrote:


The add function illustrates the kind of do-sugaring we know and love
that I want to use for Symantics.


   lam f   = unZ $ do
  show_c0 - get
  let
 vname = v ++ show_c0
 c0 = read show_c0 :: VarCount
 c1 = succ c0
 fz :: Z a String - Z b String
 fz = Z . f . unZ
  put (show c1)
  s - (fz . return) vname
  return $ (\\ ++ vname ++  -  ++ s ++ )


Now with lam, I get this cryptic error message (under 6.8.2):

Occurs check: cannot construct the infinite type: b = a - b
When trying to generalise the type inferred for `lam'
  Signature type: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
b1)
  Type to generalise: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
b1)
In the instance declaration for `Symantics (Y String)'

Both the two types in the error message are identical, which suggests
no generalization is needed.  I'm puzzled why ghc sees an infinite type.

Any ideas on how to proceed?


Not an answer, but just a different error message from GHC 6.10.3 when I 
  tried loading up your code.


kya...@kyavaio:~/tmp$ ghci EvalTaglessF.hs
GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( EvalTaglessF.hs, interpreted )

EvalTaglessF.hs:264:14:
Couldn't match expected type `b1' against inferred type `b'
  `b1' is a rigid type variable bound by
   the type signature for `fz' at EvalTaglessF.hs:263:31
  `b' is a rigid type variable bound by
  the type signature for `lam' at EvalTaglessF.hs:248:26
  Expected type: Z b1 String
  Inferred type: Z b String
In the expression: Z . f . unZ
In the definition of `fz': fz = Z . f . unZ

EvalTaglessF.hs:264:22:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
   the type signature for `fz' at EvalTaglessF.hs:263:17
  `a' is a rigid type variable bound by
  the type signature for `lam' at EvalTaglessF.hs:248:16
  Expected type: Z a1 String
  Inferred type: Z a String
In the second argument of `(.)', namely `unZ'
In the second argument of `(.)', namely `f . unZ'
Failed, modules loaded: none.



I hope this gives you a hint, if any.  I am not exactly sure about how 
to solve this but I might try using scoped type variables extension 
somehow if I were in your shoe.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Flipping *-*-* kinds, or monadic finally-tagless madness

2009-07-02 Thread Edward Kmett
Actually the problem lies in your definition of fz, it has the wrong type to
be used in lam.
The Z you get out of fz as type Z b String, but you need it to have Z (a -
b) String so that when you strip off the Z you have a Y String (a - b)
matching the result type of lam.

To get there replace your definition of fz with:

 fz :: Z a String - Z (a - b) String
 fz = Z . Y . unY . f . unZ

In 6.10.2 I used {-# LANGUAGE FlexibleInstances, TypeSynonymInstances,
MultiParamTypeClasses, ScopedTypeVariables  #-}

and that compiled just fine.

On Thu, Jul 2, 2009 at 8:02 PM, Ahn, Ki Yung kya...@gmail.com wrote:

 Kim-Ee Yeoh wrote:


 The add function illustrates the kind of do-sugaring we know and love
 that I want to use for Symantics.

lam f   = unZ $ do
  show_c0 - get
  let
 vname = v ++ show_c0
 c0 = read show_c0 :: VarCount
 c1 = succ c0
 fz :: Z a String - Z b String
 fz = Z . f . unZ
  put (show c1)
  s - (fz . return) vname
  return $ (\\ ++ vname ++  -  ++ s ++ )


 Now with lam, I get this cryptic error message (under 6.8.2):

Occurs check: cannot construct the infinite type: b = a - b
When trying to generalise the type inferred for `lam'
  Signature type: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
 b1)
  Type to generalise: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
 b1)
In the instance declaration for `Symantics (Y String)'

 Both the two types in the error message are identical, which suggests
 no generalization is needed.  I'm puzzled why ghc sees an infinite type.

 Any ideas on how to proceed?


 Not an answer, but just a different error message from GHC 6.10.3 when I
  tried loading up your code.

 kya...@kyavaio:~/tmp$ ghci EvalTaglessF.hs
 GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer ... linking ... done.
 Loading package base ... linking ... done.
 [1 of 1] Compiling Main ( EvalTaglessF.hs, interpreted )

 EvalTaglessF.hs:264:14:
Couldn't match expected type `b1' against inferred type `b'
  `b1' is a rigid type variable bound by
   the type signature for `fz' at EvalTaglessF.hs:263:31
  `b' is a rigid type variable bound by
  the type signature for `lam' at EvalTaglessF.hs:248:26
  Expected type: Z b1 String
  Inferred type: Z b String
In the expression: Z . f . unZ
In the definition of `fz': fz = Z . f . unZ

 EvalTaglessF.hs:264:22:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
   the type signature for `fz' at EvalTaglessF.hs:263:17
  `a' is a rigid type variable bound by
  the type signature for `lam' at EvalTaglessF.hs:248:16
  Expected type: Z a1 String
  Inferred type: Z a String
In the second argument of `(.)', namely `unZ'
In the second argument of `(.)', namely `f . unZ'
 Failed, modules loaded: none.



 I hope this gives you a hint, if any.  I am not exactly sure about how to
 solve this but I might try using scoped type variables extension somehow if
 I were in your shoe.


 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] here is how I made it type check

2009-07-02 Thread Ahn, Ki Yung

I don't know if this is what you want but I was at least able to make it
to type check basically changing (fz . return) into simply return.  I
think the error message about the occurs check was because of the fz
function is used wrong (or you didn't give it a correct type).

{-# LANGUAGE NoMonomorphismRestriction,TypeSynonymInstances,FlexibleInstances,MultiParamTypeClasses,ScopedTypeVariables #-}
  -- Haskell' Committee seems to have agreed to remove the restriction

-- Tagless Typed lambda-calculus with integers and the conditional
-- in the higher-order abstract syntax.
-- Haskell itself ensures the object terms are well-typed.
-- Here we use the tagless final approach.

{- 
module EvalTaglessF where

class Symantics repr where
  l:: (repr t1 - repr t2) - repr (t1-t2)
  a:: repr (t1-t2) - repr t1 - repr t2
  i:: Int - repr Int
  (+:) :: repr Int - repr Int - repr Int		-- addition
  ifz  :: repr Int - repr t - repr t - repr t	-- if zero
  fix  :: repr ((a-b) - (a-b)) - repr (a-b)
  -- Let :: repr t1 - (repr t1 - repr t) - repr t

-- compared to EvalTaglessI, everything is in lower-case now

-- Since we rely on the metalanguage for typechecking and hence
-- type generalization, we have to use `let' of the metalanguage.
infixl 9 `a`


-- It is quite challenging to show terms. Yet, in contrast to the GADT-based
-- approach (EvalTaglessI.hs), we are able to do that, without
-- extending our language with auxiliary syntactic forms.
-- Incidentally, showing of terms is just another way of _evaluating_
-- them, to strings.

type VarCount = Int			-- to build the names of variables
newtype S t = S (VarCount - (String,VarCount))
evals (S t) = t

instance Symantics S where
l f  = S $ \c0 -
   let vname = v ++ show c0
   c1 = succ c0
   (s,c2) = evals (f (S $ \c - (vname,c))) c1
   in ((\\ ++ vname ++ -  ++ s ++ ),c2)
a e1 e2  = S $ \c0 -
	   let (s1,c1) = evals e1 c0
	   (s2,c2) = evals e2 c1
   in (( ++ s1 ++   ++ s2 ++ ),c2)
i n  = S $ \c - (show n,c)
e1 +:e2  = S $ \c0 -
	   let (s1,c1) = evals e1 c0
	   (s2,c2) = evals e2 c1
   in (( ++ s1 ++  +  ++ s2 ++ ),c2)
ifz e1 e2 e3 = S $ \c0 -
	   let (s1,c1) = evals e1 c0
	   (s2,c2) = evals e2 c1
	   (s3,c3) = evals e3 c2
   in ((ifz  ++ s1 ++   ++ s2 ++   ++ s3 ++),c3)
fix e = S $ \c0 -
	   let (s1,c1) = evals e c0
   in ((fix  ++ s1 ++ ),c1)

tshow t = fst $ evals t 0

-- We no longer need variables or the environment and we do
-- normalization by evaluation.

-- Denotational semantics. Why?
newtype D t = D t			-- This is not a tag. Why?
evald:: D t - t
evald (D t) = t

instance Symantics D where
l f  = D $ \x - evald (f (D x))
a e1 e2  = D $ (evald e1) (evald e2)
i n  = D $ n
e1 +: e2 = D $ evald e1 + evald e2
ifz e1 e2 e3 = D $ if evald e1 == 0 then evald e2 else evald e3
fix e= D $ hfix (evald e) where hfix f = f (hfix f)

{-
We can also give operational semantics, by implementing the function of the
following signature:

evalo :: (forall repr. Symantics repr = repr t) -
	 (forall repr. Symantics repr = repr t)

The signature has rank-2 type and hence this file requires a PRAGMA
declaration {-# LANGUAGE Rank2Types #-}

The implementation of evalo is exactly the partial evaluator of the
tagless final paper. Please see the paper for details.

-}

-- Tests
-- Truly the tests differ from those in EvalTaglessI.hs only in the case
-- of `syntax`: (i 1) vs (I 1), etc.

test0d = evald $ l(\vx - vx +: (i 2)) `a` (i 1) -- 3

term1 = l (\vx - ifz vx (i 1) (vx +: (i 2)))
test11d = evald $ term1
test11s = tshow $ term1 -- (\\v0- (ifz v0 1 (v0 + 2)))

test12d = evald (term1 `a` (i 2))	-- 4, as Haskell Int
-- test14  = evald (term1 `a` vx)   -- Type error! Not in scope: `vx'


term2 = l (\vx - l (\vy - vx +: vy))
-- *EvalTaglessF :t term2
-- term2 :: (Symantics repr) = repr (Int - Int - Int)

test21  = evald term2
test23d = evald (term2 `a` (i 1) `a` (i 2)) -- 3

termid = l(\vx - vx)
testid = evald termid -- testid :: t1 - t1

term2a = l (\vx - l(\vy - vx `a` vy))
{- The meta-language figured the (polymorphic) type now
 *EvalTaglessF :t term2a
 term2a :: (Symantics repr) = repr ((t1 - t2) - t1 - t2)
-}


-- No longer hidden problems
-- term3 = l (\vx - ifz vx (i 1) vy) -- Not in scope: `vy'

-- The following is a type error, we can't even enter the term
-- term4 = l (\vx - ifz vx (i 1) (vx `a` (i 1)))
{- Now we get good error messages!

Couldn't match expected type `t1 - Int'
   against inferred type `Int'
  Expected type: repr (t1 - Int)
  Inferred type: repr Int
In the first argument of `a', namely `vx'
In the third argument of `ifz', namely `(vx `a` (i 1))'
-}



-- (x+1)*y = x*y + y

-- why is this less of a cheating? Try showing the term
-- Now, 

[Haskell-cafe] Re: Flipping *-*-* kinds, or monadic finally-tagless madness

2009-07-02 Thread Ahn, Ki Yung

Edward Kmett 쓴 글:
Actually the problem lies in your definition of fz, it has the wrong 
type to be used in lam.


The Z you get out of fz as type Z b String, but you need it to have Z (a 
- b) String so that when you strip off the Z you have a Y String (a - 
b) matching the result type of lam.


To get there replace your definition of fz with:

  fz :: Z a String - Z (a - b) String
  fz = Z . Y . unY . f . unZ


I think this seems to be the Yeoh wanted.

Mine was just blinded hack just to make it type check without looking at 
what program means.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] [ghc] kind of the function arrow

2009-07-02 Thread wren ng thornton

Dominic Orchard wrote:
I was just playing around and noticed that the kind of the function 
arrow in GHC is (?? - ? - *) when I (naively) expected it to be (* - 
* - *).
After looking at 
(http://hackage.haskell.org/packages/archive/ghc/6.10.2/doc/html/Type.html#5) 
I see that the kind of (-) means that the parameter type cannot be an 
unboxed tuple, whilst the result type can be anything. Why is this?

After reading this documentation I would expect the kind (? - ? - *).


Unboxed tuples don't exist. That is, they are in evidence, but they 
don't actually have any physical representation.


The elements of an unboxed tuple are stored in registers when returning 
from a function, so that the caller can access them immediately (rather 
than needing to indirect through a pointer to a tuple). ISTR that 
because of this strategy, there are restrictions on what types of tuples 
can be unboxed. Theoretically GHC could also allow passing certain 
arguments in registers when invoking a function, but this isn't 
supported as yet.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: TernaryTrees-0.1.1.1 - An efficient ternary tree implementation of Sets and Maps

2009-07-02 Thread wren ng thornton

Don Stewart wrote:

wren:

Alex Mason wrote:
TernaryTrees is a package that extends Data.Set ad Data.Map with some  
ternary tree structures, based on the article  
[http://www.pcplus.co.uk/node/3074/] .

For the string (or rather ByteString) version:

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bytestring-trie

Which has a number of other significant performance improvements (e.g.  
node fusion, ByteString instead of String) and a highly expressive  
interface. Because it uses ByteStrings it can trie any type which can be  
serialized into a vector of bits[1], albeit indirectly.


The real trick with tries is not in just having them[2], it's in having  
the right interface to make use of what they're good at. For example, if  
I have multiple tries, I'd like to merge them without doing it element  
by element[3]. Or if I know I'm going to be making a number of similar  
queries, it'd be nice if I could cache my position in the trie[4] to  
avoid repeating the work for the prefixes of all my queries[5]. Using  
tricks like these leads to significant improvements over using them like  
hashtables; tries aren't hashtables just like lists aren't arrays.


Do you have benchmarks?



Somewhere in my email archive (care of Mark Wotton). I'll see if I can 
dig them up this weekend. The biggest issue here is finding nice 
datasets (and tasks) to give reasonable benchmarks for. Reading in all 
of /usr/dict (or the Brown corpus) and looking up all keys only gives 
one perspective (or two), and not necessarily the most helpful one for 
real world use. I haven't found any good dataset/task suites like 
there are for the Language Benchmarks Game, though I'd love to hear 
about one.


The tries /= hashtables comment stems from discussions on various 
haskell blogs with people inventing their own (or wanting to benchmark 
Data.Map vs hashtables vs tries vs bloomfilters). As a drop-in 
replacement tries will perform adequately, but they're nothing 
overwhelming; the overwhelming comes from changing the usage algorithms 
to match the stride of the datastructure. I don't think I have links 
to these discussions anymore to pull up code examples.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Flipping *-*-* kinds, or monadic finally-tagless madness

2009-07-02 Thread Edward Kmett
You might also look at doing it without all the State monad noise with
something like:
 class Symantics repr  where
int :: Int  - repr Int
add :: repr Int  - repr Int - repr Int
lam :: (repr a - repr b) - repr (a-b)
app :: repr (a - b) - repr a - repr b

 newtype Pretty a = Pretty { runPretty :: [String] - String }

 pretty :: Pretty a - String
 pretty (Pretty f) = f vars where
 vars = [ [i] | i - ['a'..'z']] ++ [i : show j | j - [1..], i -
['a'..'z'] ]

 instance Symantics Pretty where
int = Pretty . const . show
add x y = Pretty $ \vars - ( ++ runPretty x vars ++  +  ++
runPretty y vars ++ )
lam f = Pretty $ \ (v:vars) - (\\ ++ v ++ .  ++ runPretty (f (var
v)) vars ++ ) where
var = Pretty . const
app f x = Pretty $ \vars - ( ++ runPretty f vars ++   ++ runPretty
x vars ++ )

-Edward Kmett

On Thu, Jul 2, 2009 at 5:52 PM, Kim-Ee Yeoh a.biurvo...@asuhan.com wrote:


 I'm trying to write HOAS Show instances for the finally-tagless
 type-classes using actual State monads.

 The original code:
 http://okmij.org/ftp/Computation/FLOLAC/EvalTaglessF.hs

 Two type variables are needed: one to vary over the Symantics
 class (but only as a phantom type) and another to vary over the
 Monad class. Hence, the use of 2-variable type constructors.

  type VarCount = int
  newtype Y b a = Y {unY :: VarCount - (b, VarCount)}

 Not knowing of a type-level 'flip', I resort to newtype isomorphisms:

  newtype Z a b = Z {unZ :: Y b a}
  instance Monad (Z a)  where
 return x = Z $ Y $ \c  - (x,c)
 (Z (Y m)) = f  = Z $ Y $ \c0 - let (x,c1) = m c0 in (unY . unZ) (f
  x) c1-- Pace, too-strict puritans
  instance MonadState String (Z a)  where
 get   = Z $ Y $ \c - (show c, c)
 put x = Z $ Y $ \_ - ((), read x)

 So far so good.  Now for the Symantics instances (abridged).

  class Symantics repr  where
 int  :: Int  - repr Int  -- int literal
 add :: repr Int  - repr Int - repr Int
 lam :: (repr a - repr b) - repr (a-b)

  instance Symantics (Y String)  where
 int = unZ . return . show
 add x y = unZ $ do
sx - Z x
sy - Z y
return $ ( ++ sx ++  +  ++ sy ++ )

 The add function illustrates the kind of do-sugaring we know and love
 that I want to use for Symantics.

 lam f   = unZ $ do
show_c0 - get
let
   vname = v ++ show_c0
   c0 = read show_c0 :: VarCount
   c1 = succ c0
   fz :: Z a String - Z b String
   fz = Z . f . unZ
put (show c1)
s - (fz . return) vname
return $ (\\ ++ vname ++  -  ++ s ++ )

 Now with lam, I get this cryptic error message (under 6.8.2):

Occurs check: cannot construct the infinite type: b = a - b
When trying to generalise the type inferred for `lam'
  Signature type: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
 b1)
  Type to generalise: forall a1 b1.
  (Y String a1 - Y String b1) - Y String (a1 -
 b1)
In the instance declaration for `Symantics (Y String)'

 Both the two types in the error message are identical, which suggests
 no generalization is needed.  I'm puzzled why ghc sees an infinite type.

 Any ideas on how to proceed?

 --
 View this message in context:
 http://www.nabble.com/Flipping-*-%3E*-%3E*-kinds%2C-or-monadic-finally-tagless-madness-tp24314553p24314553.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] How to declare a Typeless Function

2009-07-02 Thread Fernan Bolando
Hi

I have a function that swaps rows of an array of double

swap :: Array (Int,Int) Double - [Int] - Array (Int,Int) Double

I then create a function that swaps rows of arrays of Complex Double

swap :: Array (Int, Int) (Complex Double) - [Int] - Array (Int, Int)
(Complex Double)

In reality the function swap does not care whether its working on a
double or a complex number.
how do I declare swap so that it will work whether it's a complex or a
double array.

I tried googling but I wasn't sure what to google.

fernan
-- 
http://www.fernski.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to declare a Typeless Function

2009-07-02 Thread Alexander Dunlap
swap :: Array (Int, Int) a - [Int] - Array (Int, Int) a

The lowercase a means that that type variable is polymorphic, i.e.
it can be any type.

Alex

On Thu, Jul 2, 2009 at 8:05 PM, Fernan Bolandofernanbola...@mailc.net wrote:
 Hi

 I have a function that swaps rows of an array of double

 swap :: Array (Int,Int) Double - [Int] - Array (Int,Int) Double

 I then create a function that swaps rows of arrays of Complex Double

 swap :: Array (Int, Int) (Complex Double) - [Int] - Array (Int, Int)
 (Complex Double)

 In reality the function swap does not care whether its working on a
 double or a complex number.
 how do I declare swap so that it will work whether it's a complex or a
 double array.

 I tried googling but I wasn't sure what to google.

 fernan
 --
 http://www.fernski.com
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] How to present the commonness of some objects?

2009-07-02 Thread Magicloud Magiclouds
Hi,
  I thought class was for this purpose. But it turns out not.
  Code as following could not compiled.

1 main = do
2   mapM_ (\(x, y, widget) - do
3a - widgetRun widget
4putStrLn $ show a
5 ) widgetList
6
7 widgetList :: (Widget w) = [(Integer, Integer, w)]
8 widgetList = []
9
10 class Widget w where
11   widgetRun :: w - IO ()
---
% ghc --make tmp/test.hs
[1 of 1] Compiling Main ( tmp/test.hs, /tmp/Main.o )

tmp/test.hs:3:16:
Ambiguous type variable `t' in the constraint:
  `Widget t' arising from a use of `widgetRun' at tmp/test.hs:3:16-31
Probable fix: add a type signature that fixes these type variable(s)
-- 
竹密岂妨流水过
山高哪阻野云飞
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to present the commonness of some objects?

2009-07-02 Thread Ross Mellgren

You have a couple problems here.

The first is that GHC has no idea what particular type 'w' widgetList  
has, because the empty list is polymorphic.


The second is that it looks like you probably want a heterogeneous  
list of widgets -- that is, possibly different types of widget as long  
as they all conform to Widget. To do this you'll need  
ExistentialQuantification (or GADTs I guess?).


For example:

{-# LANGUAGE ExistentialQuantification #-}

class Widget w where
widgetRun :: w - IO ()

data SomeWidget = forall w. Widget w = SomeWidget w

widgetList :: [(Integer, Integer, SomeWidget)]
widgetList = []

main = mapM aux widgetList
aux (x, y, sw) =
case sw of
SomeWidget w - widgetRun w

Note that the type variable for widgetList 'w' has disappeared.  
Before, with the type variable 'w', all elements of the widgetList had  
to be of the same type (lists being homogeneous). By wrapping up the  
type variable 'w' inside SomeWidget, you can now have whatever types  
of widgets in that SomeWidget, e.g.


data Button = Button (IO ())
instance Widget Button where widgetRun = ...

data Label = Label (String - IO ())
instance Widget Label where widgetRun = ...

widgetList:: [(Integer, Integer, SomeWidget)]
widgetList =
[ SomeWidget (Button $ putStrLn ding!)
, SomeWidget (Label $ putStrLn . (entered:  ++)) ]

Before, without existential quantification, you had to have all the  
same type of widget (e.g. all Button or all Label)


Hope this makes it more clear.

-Ross

On Jul 3, 2009, at 12:00 AM, Magicloud Magiclouds wrote:


Hi,
 I thought class was for this purpose. But it turns out not.
 Code as following could not compiled.

1 main = do
2   mapM_ (\(x, y, widget) - do
3a - widgetRun widget
4putStrLn $ show a
5 ) widgetList
6
7 widgetList :: (Widget w) = [(Integer, Integer, w)]
8 widgetList = []
9
10 class Widget w where
11   widgetRun :: w - IO ()
---
% ghc --make tmp/test.hs
[1 of 1] Compiling Main ( tmp/test.hs, /tmp/Main.o )

tmp/test.hs:3:16:
   Ambiguous type variable `t' in the constraint:
 `Widget t' arising from a use of `widgetRun' at tmp/test.hs: 
3:16-31
   Probable fix: add a type signature that fixes these type  
variable(s)

--
竹密岂妨流水过
山高哪阻野云飞
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to present the commonness of some objects?

2009-07-02 Thread Magicloud Magiclouds
Wow, this complex Thank you. I will try that.

On Fri, Jul 3, 2009 at 12:24 PM, Ross Mellgrenrmm-hask...@z.odi.ac wrote:
 You have a couple problems here.

 The first is that GHC has no idea what particular type 'w' widgetList has,
 because the empty list is polymorphic.

 The second is that it looks like you probably want a heterogeneous list of
 widgets -- that is, possibly different types of widget as long as they all
 conform to Widget. To do this you'll need ExistentialQuantification (or
 GADTs I guess?).

 For example:

 {-# LANGUAGE ExistentialQuantification #-}

 class Widget w where
    widgetRun :: w - IO ()

 data SomeWidget = forall w. Widget w = SomeWidget w

 widgetList :: [(Integer, Integer, SomeWidget)]
 widgetList = []

 main = mapM aux widgetList
    aux (x, y, sw) =
        case sw of
            SomeWidget w - widgetRun w

 Note that the type variable for widgetList 'w' has disappeared. Before, with
 the type variable 'w', all elements of the widgetList had to be of the same
 type (lists being homogeneous). By wrapping up the type variable 'w' inside
 SomeWidget, you can now have whatever types of widgets in that SomeWidget,
 e.g.

 data Button = Button (IO ())
 instance Widget Button where widgetRun = ...

 data Label = Label (String - IO ())
 instance Widget Label where widgetRun = ...

 widgetList:: [(Integer, Integer, SomeWidget)]
 widgetList =
    [ SomeWidget (Button $ putStrLn ding!)
    , SomeWidget (Label $ putStrLn . (entered:  ++)) ]

 Before, without existential quantification, you had to have all the same
 type of widget (e.g. all Button or all Label)

 Hope this makes it more clear.

 -Ross

 On Jul 3, 2009, at 12:00 AM, Magicloud Magiclouds wrote:

 Hi,
  I thought class was for this purpose. But it turns out not.
  Code as following could not compiled.

 1 main = do
 2   mapM_ (\(x, y, widget) - do
 3            a - widgetRun widget
 4            putStrLn $ show a
 5         ) widgetList
 6
 7 widgetList :: (Widget w) = [(Integer, Integer, w)]
 8 widgetList = []
 9
 10 class Widget w where
 11   widgetRun :: w - IO ()
 ---
 % ghc --make tmp/test.hs
 [1 of 1] Compiling Main             ( tmp/test.hs, /tmp/Main.o )

 tmp/test.hs:3:16:
   Ambiguous type variable `t' in the constraint:
     `Widget t' arising from a use of `widgetRun' at tmp/test.hs:3:16-31
   Probable fix: add a type signature that fixes these type variable(s)
 --
 竹密岂妨流水过
 山高哪阻野云飞
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe





-- 
竹密岂妨流水过
山高哪阻野云飞
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe