Re: [Haskell-cafe] Suggestions for improvement

2010-10-03 Thread Victor Nazarov
I suggest to pay more attention to haskell's standard library.

"allButLast" is called "init" in Data.List module.

Second, do not use explicit recursion. You can capture recursion using
some high-order function like map, filter, foldr and so on:

lastToTheLength xs = map f xs
  where f = const . last $ xs

And last, your type signatures are too restrictive. You can apply your
functions to arbitrary lists.

lastToTheLength :: [a] -> [a]

Standard library knowledge is very helpful in producing short and
clear definitions.

blowup = concat . zipWith replicate [1..]

On Mon, Oct 4, 2010 at 1:24 AM, Dominique Devriese
 wrote:
> Gregory,
>
> 2010/10/3 Gregory Crosswhite :
>>  On 10/3/10 1:45 PM, Dominique Devriese wrote:
>>>
>>> Additionally, you can't combine the functions (blowup . allButLast)
>>> and lastToTheLength into a function that returns a pair like you seem
>>> to attempt. You need a function like the following for that:
>>>
>>> comma :: (a ->  b) ->  (a ->  c) ->  a ->  (b,c)
>>> comma f g x = (f x, g x)
>>>
>>> Then you could say:
>>>
>>> blowup = (uncurry (++)) . comma (blowup . allButLast) lastToTheLength
>>
>> It is worth noting that such a function already exists in the standard
>> libraries;  it is the &&& operator in Control.Arrow:
>>
>>    blowup = uncurry (++) . (blowup . allButLast &&& lastToTheLength)
>
> Or you can write it as (liftA2 (,)) as I noted a few lines further in my mail 
> ;)
>
> Dominique
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>



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


[Haskell-cafe] [ANNAUNCE] ghcjs-0.1.0 Haskell to Javascript compiler

2010-10-20 Thread Victor Nazarov
I've been working on this for some month and I think now I'm ready to
share the results.

http://github.com/sviperll/ghcjs

Haskell to Javascript translator


Project aims to provide solution to

 * compile modern Haskell libraries to Javascript files and use
   them in Ajax applications or
 * develop entire Ajax application in Haskell language

Building


Code builds as standard haskell package

$ runghc Setup configure
$ runghc Setup build
$ runghc Setup install

Usage
-

To compile Haskell module to Javascript use `ghcjs` command.

$ ghcjs Test.hs

This command is merely equivalent to the following

$ ghc --make Test.hs

but it compiles to Javascript instead of native code.

See examples folder for an example of loading and running haskell code
from browser.

Status
--

The code is in alpha stage. Feel free to experiment with it as you wish.

Implementation
--

Compiler is implemented as [GHC](http://www.haskell.org/ghc/) backend
using GHC API. And been tested with GHC 6.12.1.

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


Re: [Haskell-cafe] [ANNAUNCE] ghcjs-0.1.0 Haskell to Javascript compiler

2010-10-21 Thread Victor Nazarov
On Thu, Oct 21, 2010 at 6:35 AM, Richard O'Keefe  wrote:
>
> On 21/10/2010, at 12:01 PM, Victor Nazarov wrote:
>
>> I've been working on this for some month and I think now I'm ready to
>> share the results.
>
> Given that this is alpha code, what's the performance like?
>

I don't have any numbers, yet. But can you suggest any benchmarks that
can be used to measure performance. Preferably, benchmarks shouldn't
use any low level stuff and Haskell IO.

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


Re: [Haskell-cafe] [ANNAUNCE] ghcjs-0.1.0 Haskell to Javascript compiler

2010-10-27 Thread Victor Nazarov
On Wed, Oct 27, 2010 at 4:30 PM, Martijn Schrage  wrote:
> On 21-10-10 01:01, Victor Nazarov wrote:
>>
>> I've been working on this for some month and I think now I'm ready to
>> share the results.
>
> Great stuff! I've been looking for something like this for a long time.
>
> If you add "|| transport.status == 0" to line 90 of examples/rts-common.js,
> it also works on a local file system.
>

Thank you, I'll fix it.

> I played around with it a bit to see how easy it was to call JavaScript from
> Haskell, and it turned out to be straightforward. With a little guessing, I
> constructed a JavaScript representation of a thunk, which evaluates its
> string argument as a JavaScript expression and returns the resulting string
> to Haskell. This thunk can be passed to the JavaScript-compiled Haskell
> function. To pass it around in Haskell and force its evaluation, I
> constructed a simple monad.
>

Very cool. I'll incorporate your changes, If you don't mind.
However, I have some minor remarks.
You shouldn't override hscall function, or you may break partial
application implementation. And you shouldn't overide properties of
evalFn, I wonder that this doesn't break your example...

var evalFn = new $hs.Func(1);
evalFn.evaluate(arg) = function(arg) {
  var argStr = $hs.fromHaskellString(arg);
  var res = eval(argStr);
  return $hs.toHaskellString(arg); // This function should be added to
$hs object/namespace
}

> Now, on your web page, you can do something like:
>
> 
>
> and in a Haskell module:
>
> validate :: JS ()
> validate =
>  do { inputValue <- eval "document.getElementById('inputField').value"
>    ; exec $ "document.getElementById('inputField').style.backgroundColor="++
>             color inputValue
>    }
>  where color str = if and (map isDigit str) then "'white'" else "'red'"
>

I think we should do something like this:

data JsObject = ... -- Should be made abstract

and

eval :: String -> [JsObject] -> JS JsObject

So we can pass around javascript-objects in haskell program and bind
them back into javascript calls.
And use some conversion functions in case when we need data:

jsObjectToString :: JsObject -> JS String
jsObjectToInt :: JsObject -> JS Int

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


Re: [Haskell-cafe] [ANNAUNCE] ghcjs-0.1.0 Haskell to Javascript compiler

2010-10-27 Thread Victor Nazarov
On Wed, Oct 27, 2010 at 5:25 PM, Ryan Yates  wrote:
> I ran into a problem with line 31 of examples/rts-common.js when running on
> Chrome:
>>    var word16addCarry = function function(a, b, c) {
> Shouldn't that be:
>>    var word16addCarry = function(a, b, c) {

Yes, that's my fault. I'll fix it.

> With that change it runs fine for me (GHC 6.12.3).  Chrome also wasn't happy
> loading from the local file system (Cross origin requests are only supported
> for HTTP), so I just used happstack to test:
>>    import Happstack.Server
>>    main = simpleHTTP nullConf (fileServe [] "./")
>
>

I wasn't able to run it in Chrome without dedicated HTTP-server, seems
like it is the only way...

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


Re: [Haskell-cafe] [ANNAUNCE] ghcjs-0.1.0 Haskell to Javascript compiler

2010-10-28 Thread Victor Nazarov
On Wed, Oct 27, 2010 at 7:46 PM, Martijn Schrage  wrote:
> On 27-10-10 16:20, Victor Nazarov wrote:
>>
>> Very cool. I'll incorporate your changes, If you don't mind.
>
> Not at all.
>>
>> However, I have some minor remarks.
>> You shouldn't override hscall function, or you may break partial
>> application implementation. And you shouldn't overide properties of
>> evalFn, I wonder that this doesn't break your example...
>
> Ah, yes, that was the guessing part. I just hacked around a bit and thought
> I'd leave the correct definition to someone who actually knows what they're
> doing :-)
>>
>> var evalFn = new $hs.Func(1);
>> evalFn.evaluate(arg) = function(arg) {
>>   var argStr = $hs.fromHaskellString(arg);
>>   var res = eval(argStr);
>>   return $hs.toHaskellString(arg); // This function should be added to
>> $hs object/namespace
>> }
>
> This works without any problems (after changing the second line to:
> "evalFn.evaluate = function(arg) {")
>>
>> I think we should do something like this:
>>
>> data JsObject = ... -- Should be made abstract
>>
>> and
>>
>> eval :: String ->  [JsObject] ->  JS JsObject
>>
>> So we can pass around javascript-objects in haskell program and bind
>> them back into javascript calls.
>> And use some conversion functions in case when we need data:
>>
>> jsObjectToString :: JsObject ->  JS String
>> jsObjectToInt :: JsObject ->  JS Int
>
> Yes, that seems logical. The JsObjects can then be treated similar to
> IORefs.
>
> What are your plans with the package? In my opinion, this work could be
> extremely useful for building Ajax apps, and it doesn't seem to be that far
> from being usable already.
>
> Some interesting near-future work I can think of:
>
> - Make it work on all major browsers
This shouldn't be a problem...

> - A faster and more robust module loader (now it loses a lot of time on 404
> errors, trying to access modules in the wrong package dir)
I agree that this is important. I'll look into it...

> - Basic type checking for the top-level Haskell functions
I think this should be implemented via FFI export implementation.

> - Marshaling between Haskell and JavaScript values
Again It's mostly implementation of Haskell FFI

> - JQuery support
> - Nice ways to build JavaScript (and JQuery) expressions in Haskell
Dmitry Golubovski had a code generator from WebIDL wich he used to
support HTML5 DOM in YHC.

> - Support more libraries and packages (Parsec would be interesting)
>
I think Parsec should work right now out of the box. But I don't have
time to investigate it...

> I can find some spare time to work on this. I'm sure there will be others as
> well.
>

I want to make code generator more smart and generate more optimized
code. To archive this I need to rewrite it in Monad or
ApplicativeFunctor style. I need Reader monad there to pass some
environment.

I think ghc-packages support is rather trivial to add. So module
loader will always know the one true location of module.

I want to implement continuation passing style calling convention for
Haskell-values as an alternative to two existing ones: plain and
trampoline. This will even allow multithreading emulation (with
setTimer as a scheduling mechanism...)

And last, I want to dig into FFI implementation. I think GHC doesn't
allow extensible FFI. So you won't be able to write "javascript"
calling convention in Haskell source file. But I think we can overcome
this using "ccall" for example...

I don't know what tasks are of most priority. I do what I feel like
doing :) I'll be very interested to see what other people can do with
all this. And I think that we should switch to application driven
development some time with something like Yampa-based game running in
web-browser...

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


Re: [Haskell-cafe] ANN: unordered-containers - a new, faster hashing-based containers library

2011-02-23 Thread Victor Nazarov
On Sat, Feb 19, 2011 at 4:38 AM, Johan Tibell  wrote:
> Hi all,
>
> I am delighted to announce the release of preview versions of two new 
> packages:
>
> unordered-containers 0.1
> Efficient hashing-based container types.
> http://hackage.haskell.org/package/unordered-containers
>
> hashable 1.1
> Efficient hashing of common types.
> http://hackage.haskell.org/package/hashable
>
> These packages address a need for faster container types in Haskell,
> especially for string types like ByteString and Text. The package
> achieves better performance by using hashing and a Patricia trie (also
> known as a radix tree), instead of a balanced tree, in its
> implementation.
>
> The provided HashMap type is three times faster than Data.Map for
> lookups and twice as fast for inserts, for all key types I've tried,
> including ByteString, String, and Int.
>
> I'm calling this a preview release, even though the code hash been
> well tested both for correctness and performance, as the API is quite
> basic and doesn't provide a HashSet type yet. One thing you'll notice
> is that the API is split into a value-strict and a value-lazy version,
> making it easier to use in a strict setting.
>
> If you want to contribute, please get copies of the source trees from here:
>
> * git clone https://github.com/tibbe/unordered-containers.git
> * git clone https://github.com/tibbe/hashable.git
>
> Alternatively, just fork the projects on GitHub:
>
> http://github.com/tibbe
>
> As I mentioned in my talk on hashing-based containers earlier this
> week, I'm working on an even faster version, based on hash-array
> mapped tries, but it won't be ready until GHC 7.2.
>
> Johan
>

What about making Hashable subclass of Eq

class Eq a => Hashable a where

I think it's is obvious from Hasable class properties that some kind
of equality is needed and I think it will reduce type class
constraints in actual hash table implementation in
unordered-containers package.

Also I think that value of hash functions is obviously a Monoid and it
will be convenient to have Monoid instance

newtype Hash = Hash Int
instance Monoid Hash where
  mempty = Hash 0
  Hash a `mappend` Hash b = Hash (a `combine` b)

class Eq a => Hashable a where
hash :: a -> Hash
hashWithSalt :: Hash -> a -> Hash

hashWithSalt salt x = salt `mappend` hash x

-- 
Victor Nazarov

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


Re: [Haskell-cafe] Why the reluctance to introduce the Functor requirement on Monad?

2011-07-26 Thread Victor Nazarov
On Tue, Jul 26, 2011 at 1:01 PM, Alejandro Serrano Mena
 wrote:
> I'll give my two cents about some design I've been thinking about. Instead
> of trying to derive all instances automatically, the programmer should
> explicitly tell them (so the problems about conflicting implementations
> would be minimised). I attach a piece of code of what I think could be done:
> instance Functor a <= Monad a where  -- notice the reversed "<="
>   fmap = ...
> from Monad MyMonad derive Functor MyMonad
> With the from_derive_ clause, we are telling exactly from which "<="
> declaration to pull the definition from. The part of "from" should have
> already been written or derived, so we know exactly which instance the user
> is speaking about.
> More refinements to the syntax could be done, for example if we have:
> instance Functor a <= Applicative a where
>   fmap = ..
> instance Applicative a <= Monad a where
>   pure = ...
>   (<*>) = ...
> Then, writing "from Monad MyMonad derive Functor MyMonad" would go through
> the entire tree of "reverse instance declarations" and create instances for
> Applicative, and from that a Functor one (of course, this should fail if we
> have more than one path, then the user should write the path explicitly as
> "from Monad M derive Applicative M; from Applicative M derive Functor M").
> But it has the advantage of allowing later addition of classes in the path,
> that would be derived when recompiling the code that uses it.

I want to support explicit intance derivation. But I'd like to suggest
slightly less radical syntax extention:

-- class definition:
class Fuctor m => Monad m
  where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
join :: m (m a) -> m a

-- default implementations:
   a >> b = a >>= (\_ -> b)
   a >>= f = join . fmap f $ a
   join a = a >>= id

   -- default instances:
   instance Functor m
 where
   fmap f a = a >>= (return . f)

newtype Reader a b = Reader { runReader :: a -> b }

-- instace declaration:
instance Monad (Reader r)
  where
return = Reader . const
m >>= f = Reader $ \r -> runReader (f (runReader m r)) r
  deriving (Functor)

So syntax changes are very minor.

-- 
Victor Nazarov

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


Re: [Haskell-cafe] Tupling functions

2011-09-14 Thread Victor Nazarov
On Wed, Sep 14, 2011 at 6:45 AM, Casey McCann  wrote:
> On Tue, Sep 13, 2011 at 10:03 PM, Chris Smith  wrote:
>> Ah, okay... then sure, you can do this:
>>
>> class Tuple a b c | a b -> c where
>>    tuple :: a -> b -> c
>>
>> instance Tuple (a -> b, a -> c) a (b,c) where
>>    tuple (f,g) x = (f x, g x)
>
> This wouldn't actually work well in practice. There's no dependency
> between the various occurrences of "a" in the types, so unless they're
> already known to be the same, GHC will complain about an ambiguous
> instance (please excuse the silly GHCi prompt):
>
>    Ok, modules loaded: Tupling.
>    ∀x. x ⊢ tuple ((+3), show) 4
>
>    :0:1:
>        No instance for (Tuple (a0 -> a0, a1 -> String) b0 c0)
>          arising from a use of `tuple'
>
> Given that the class is only intended to be used where those types are
> equal, you really want it to unify them based on use of the tuple
> function.
>
>> and so on...  You'll need fundeps (or type families if you prefer to
>> write it that way), and probably at least flexible and/or overlapping
>> instances, too, but of course GHC will tell you about those.
>
> I rather prefer type families in this case, both because the problem
> is easily expressed in "type function" style, and because it gives you
> an easy type equality constraint to use, rather than using arcane
> trickery with overlaps to force post-hoc unification. We'd probably
> want to do something like this:
>
>    class Tuple t where
>        type Arg t :: *
>        type Result t :: *
>        tuple :: t -> Arg t -> Result t
>
>    instance (x1 ~ x2) => Tuple (x1 -> a, x2 -> b) where
>        type Arg (x1 -> a, x2 -> b) = x1
>        type Result (x1 -> a, x2 -> b) = (a, b)
>        tuple (f, g) x = (f x, g x)
>
>    instance (x1 ~ x2, x2 ~ x3) => Tuple (x1 -> a, x2 -> b, x3 -> c) where
>        type Arg (x1 -> a, x2 -> b, x3 -> c) = x1
>        type Result (x1 -> a, x2 -> b, x3 -> c) = (a, b, c)
>        tuple (f, g, h) x = (f x, g x, h x)
>
> Used like so:
>
>    Ok, modules loaded: Tupling.
>    ∀x. x ⊢ tuple ((+2), show, (< 2)) 3
>    (5,"3",False)
>
> Note that not only does this avoid ambiguity, it even unifies
> ambiguous types that are then defaulted by the usual means.
>
> That said, I question the utility of a class like this. The
> boilerplate instances are tedious to write and it's not flexible in
> any way; tuples not being defined inductively makes them a real pain
> to work with unless there's a particularly good reason to do so.
> Something equivalent to right-nested (,) with () as a terminator is
> much more pleasant, and since we're deep in the pits of
> non-portability anyway, might as well pull out bang patterns and
> UNPACK pragmas if avoiding extra bottoms was the reason for using
> plain tuples.
>

I've just tried another approach (code below). And GHC even inferred
type for tupleF. But I think GHC inferred the wrong type and I can't
formulate the right one, it seems to require infinite number of
constraints. With GHC inferred type this function is not usable,
though:

*Tuples> tupleF ((+2), show, (<2)) 3

:1:0:
Couldn't match expected type `TTail
(a -> a, a1 -> String, a2 -> Bool)'
   against inferred type `(a -> a, a1 -> String, a2 -> Bool)'
  NB: `TTail' is a type function, and may not be injective
When generalising the type(s) for `it'

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
module Tuples where

class Tuple t
class (Tuple t, Tuple (TTail t)) => NTuple t
  where
type THead t :: *
type TTail t :: *
thead :: t -> THead t
ttail :: t -> TTail t
tcons :: THead t -> TTail t -> t

newtype Tuple1 a = Tuple1 a

instance Tuple ()
instance Tuple (Tuple1 a)
instance NTuple (Tuple1 a)
  where
type THead (Tuple1 a) = a
type TTail (Tuple1 a) = ()
thead (Tuple1 a) = a
ttail (Tuple1 a) = ()
tcons a b = Tuple1 a
instance Tuple (a, b)
instance NTuple (a, b)
  where
type THead (a, b) = a
type TTail (a, b) = Tuple1 b
thead (a, b) = a
ttail (a, b) = Tuple1 b
tcons a (Tuple1 b) = (a, b)
instance Tuple (a, b, c)
instance NTuple (a, b, c)
  where
type THead (a, b, c) = a
type TTail (a, b, c) = (b, c)
thead (a, b, c) = a
ttail (a, b, c) = (b, c)
tcons a (b, c) = (a, b, c)

tupleF t a = thead t a `tcons` tupleF (ttail t) a


-- 
Victor Nazarov

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


Re: [Haskell-cafe] Poll: Do you want a mascot?

2011-11-24 Thread Victor Nazarov
I have the same position. want a good mascot... Count this as yes.

2011/11/23 Gábor Lehel :
> I don't want a bad mascot. I do want a good mascot.
>
> If you must count me down for one side or the other, count this as a yes.
>
> On Wed, Nov 23, 2011 at 8:11 PM, heathmatlock  wrote:
>> Question: Do you want a mascot?
>> Answers:
>> Yes
>> No
>>
>> --
>> This is an attempt to figure out if this idea is going anywhere.
>> ___
>> Haskell-Cafe mailing list
>> Haskell-Cafe@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>
>
>
> --
> Work is punishment for failing to procrastinate effectively.
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>



-- 
Victor Nazarov

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


[Haskell-cafe] Help using catch in 6.10

2009-02-20 Thread Victor Nazarov
Hello, cafe.

I whant to switch to GHC 6.10

My application compiled fine with 6.8.3, but after switchin to 6.10,
I've got errors about usage of catch function:

Main.hs:165:14:
Ambiguous type variable `e2' in the constraint:
  `Exception e2' arising from a use of `catch' at Main.hs:165:14-38
Probable fix: add a type signature that fixes these type variable(s)

Main.hs:261:17:
Ambiguous type variable `e' in the constraint:
  `Exception e' arising from a use of `handle' at Main.hs:261:17-118
Probable fix: add a type signature that fixes these type variable(s)

Relevant places in code are:

...
 getNSteps f =
   do text <- get entryNSteps entryText
  catch (readIO text >>= f) $ \_e ->
do msgBox (Just window) [] MessageWarning ButtonsOk $
"Число шагов указано неверно: " ++ show text
   return ()
...
loadData :: IO ([Term], Map.Map String Term)
loadData =
  do examples <- handle (\_e -> msgBox Nothing [] MessageWarning
ButtonsOk "Ошибка чтения файла примеров" >> return []) $
   do examplesLines <- fmap lines $ readFile "examples.txt"
  let parsings :: [Term]
  parsings = concatMap (fromEither . parse) examplesLines
  parse :: String -> Either ParseError Term
  parse = Parsec.parse (Lambda.parser >>= \t -> skipMany
space >> eof >> return t) ""
  fromEither :: Either ParseError Term -> [Term]
  fromEither = either (const []) (\t -> [t])
  return parsings
...


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


[Haskell-cafe] base-4 + gtk2hs-0.10.0 licensing

2009-02-25 Thread Victor Nazarov
I wonder what software licence I can use to release my application.
I've developed some education tool with the following dependencies:

% ghci Main.hs
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: Main, UI, Lambda, Lambda.Eval, Lambda.Zipper,
Lambda.Show, Lambda.Parser, Lambda.Common.
Prelude Main> main
Loading package syb ... linking ... done.
Loading package array-0.2.0.0 ... linking ... done.
Loading package containers-0.2.0.0 ... linking ... done.
Loading package bytestring-0.9.1.4 ... linking ... done.
Loading package Win32-2.2.0.0 ... linking ... done.
Loading package parsec-2.1.0.1 ... linking ... done.
Loading package mtl-1.1.0.2 ... linking ... done.
Loading package old-locale-1.0.0.1 ... linking ... done.
Loading package time-1.1.2.2 ... linking ... done.
Loading package glib-0.10.0 ... linking ... done.
Loading package cairo-0.10.0 ... linking ... done.
Loading package gtk-0.10.0 ... linking ... done.
Loading package glade-0.10.0 ... linking ... done.

I just don't know the options and I think licensing is subtle enough
to ask for suggestions.

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


[Haskell-cafe] History data structure suggestion

2009-04-12 Thread Victor Nazarov
Hello,

I have a gtk2hs application. I'd like to implement some kind of browser
history for it. It should have Back and Forward buttons and a popup menu
with radio items.History is a list of strings. There is a current position
in this list, so you can move this position back and forward.
Some kind of list zipper must be enough to implement this:
data History a = Empty | Hist { histBefore :: [a], histCurrent :: a,
histAfter :: [a] }

back, forward:: History a -> History a
back (Hist (b:bs) c as) = Hist bs b (c:as)
forward (Hist bs c (a:as)) = Hist (c:bs) a as

add :: a -> History a -> History a
add x (Hist bs c _) = Hist (c:bs) x [] --- When you add something, future
part of history becomes blank.
add x Empty = Hist [] x []

start :: History a -> History a
start (Hist bs c as) = Hist [] h (hs ++ [c] ++ as)
  where (h:hs) = reverse bs

But there is another requirement. There must be some "points" in the history
to store in popup menu. When you select any point the history sould be
rolled to this point.
For example.
data HistPoint a = HP Int

current :: History a -> HistPoint a
current (Hist bs _ _) = HP (length bs)

goTo :: HistPoint a -> History a -> History a
goTo (HP n) = foldr1 (.) (replicate n forward) . start

I wonder is there more effective, more easy to implement data structure to
represent History and HistPoint

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


Re: [Haskell-cafe] Re: Cabal's default install location

2009-04-22 Thread Victor Nazarov
On Wed, Apr 22, 2009 at 2:06 PM, Duncan Coutts
wrote:

> On Wed, 2009-04-22 at 11:33 +0200, david48 wrote:
> >
> > The default should at least be consistent among cabal install, runghc
> > Setup.hs, installing GHC, Gtk2Hs, and so on.
> >
> > If GHC is installed in /home/myusername/local,
>
> Where you choose to install ghc is not related.
>
> > what does cabal install --global ?
>
> Global always means /usr/local by default, unless you change it in the
> cabal config file.
>
> By default ghc, gtk2hs also install globally in /usr/local (unless you
> specify a --prefix.)
>
> This tradition of global and /usr/local for ./configure scripts is ok,
> but for a convenient package manager it's not necessarily ideal.
>
> Ubuntu/Debian policy seems to be installation into /var/lib/cabal . So it's
clear that the whole hierarchy is managed by single tool cabal. Drawback is
that you should add /var/lib/cabal/bin into your PATH.

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


Re: [Haskell-cafe] calling a variable length parameter lambda expression

2009-05-06 Thread Victor Nazarov
On Tue, May 5, 2009 at 8:49 PM, Nico Rolle  wrote:

> Hi everyone.
>
> I have a problem.
> A function is recieving a lambda expression like this:
> (\ x y -> x > y)
> or like this
> (\ x y z a -> (x > y) && (z < a)
>
> my problem is now i know i have a list filled with the parameters for
> the lambda expression.
> but how can i call that expression?
> [parameters] is my list of parameters for the lambda expression.
> lambda_ex is my lambda expression
>
> is there a function wich can do smth like that?
>
> lambda _ex (unfold_parameters parameters)
>

Why not:

lam1 = \[x, y] -> x > y
lam2 = \[x, y, z, a] -> (x > y) && (z < a)

doLam :: Ord a => ([a] -> Bool) -> [a] -> Bool
doLam lam params = lam params

So, this will work fine:

doLam lam1 [1, 2]
doLam lam2 [1,2,3,4]

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


Re: [Haskell-cafe] calling a variable length parameter lambda expression

2009-05-07 Thread Victor Nazarov
On Wed, May 6, 2009 at 7:44 PM, Daniel Peebles  wrote:

> Keep in mind that using lists for your parameters means you lose
> static guarantees that you've passed the correct number of arguments
> to a function (so you could crash at runtime if you pass too few or
> too many parameters to a function).
>

Yes, program will crash with error "Pattern match failure" or smth like
that. And yes, doLam is just an id with restricted type. My solution is
close to what seems the most common way of passing arguments in Scheme, and
the payoff is Scheme's dynamic typing...

This solution is not the Haskell way and should be avoid.

--
Victor Nazarov


> On Wed, May 6, 2009 at 11:41 AM, Nico Rolle  wrote:
> > super nice.
> > best solution for me so far.
> > big thanks.
> > regards
> >
> > 2009/5/6 Victor Nazarov :
> >> On Tue, May 5, 2009 at 8:49 PM, Nico Rolle  wrote:
> >>>
> >>> Hi everyone.
> >>>
> >>> I have a problem.
> >>> A function is recieving a lambda expression like this:
> >>> (\ x y -> x > y)
> >>> or like this
> >>> (\ x y z a -> (x > y) && (z < a)
> >>>
> >>> my problem is now i know i have a list filled with the parameters for
> >>> the lambda expression.
> >>> but how can i call that expression?
> >>> [parameters] is my list of parameters for the lambda expression.
> >>> lambda_ex is my lambda expression
> >>>
> >>> is there a function wich can do smth like that?
> >>>
> >>> lambda _ex (unfold_parameters parameters)
> >>
> >> Why not:
> >>
> >> lam1 = \[x, y] -> x > y
> >> lam2 = \[x, y, z, a] -> (x > y) && (z < a)
> >>
> >> doLam :: Ord a => ([a] -> Bool) -> [a] -> Bool
> >> doLam lam params = lam params
> >>
> >> So, this will work fine:
> >>
> >> doLam lam1 [1, 2]
> >> doLam lam2 [1,2,3,4]
> >>
> >> --
> >> Victor Nazarov
> >>
> > ___
> > 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] diff implementation in haskell

2009-12-06 Thread Victor Nazarov
Are there pure haskell implementations of diff and diff3 algorithms. Like:

> data Diff a = Deleted [a] | Common [a] | Added [a]
>
> diff :: Eq a => [a] -> [a] -> [Diff a]
>
> diff3 :: Eq a => [a] -> [a] -> [a] -> [a]

or smth more general like:

> class Diff a where
>   type Difference a
>   diff :: a -> a -> Difference a
>   patch :: a -> Difference a -> a
>
> prop_diffpatch a b = patch a (diff a b) == b

?

If not, where can I start towards the implementation? What's the way
to do it more functionally?
--
Victor Nazarov
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] GUI programming

2010-02-02 Thread Victor Nazarov
Hello,

I've been writing some GUI application with Gtk2hs. It's an
interpreter for lambda-calculus and combinatory logic, it's GPL and if
you interested I can share it with cafe.

The problem is that the GUI code has become very ugly and I'm tempted
to rewrite it totally. I've been looking forward to the FRP stuff, but
I've never seen a single definition of the term. Conal Eliot's
"denotational programming" is too general to be definition. I want to
try Grapefruit, but I got totally lost when I see arrow notation.

I consider more lightweight and more imperative approach, something
closer to CSP (Communicating Secuential Processes) then FRP. I've just
crafted some sample program to illustrate my idea.

The behaviour is a monad and it's IO monad so you can do any IO
(Gtk2hs) programming you wish. The differences is that you don't
attach static event handlers and tries to determine what to do
dependent on application state. You attach and detach handlers as much
as possible. Behaviour looks like a process that can stop execution
and wait for some GUI event. When event arrived it continues
execution.

Do you see this approach viable. There are steel some details to emerge:
* How to wait for several events
* How to handle IO exceptions

Here is the code:
{-# LANGUAGE ExistentialQuantification #-}
module Main where

import Data.IORef
import System.Glib
import Graphics.UI.Gtk
import Control.Monad.Trans

type Event obj = IO () -> IO (ConnectId obj)

data Behaviour a =
  forall b. BBind (Behaviour b) (b -> Behaviour a)
  | BIO (IO a)
  | forall obj. GObjectClass obj => BWaitEvent (Event obj) (Behaviour a)

instance Monad Behaviour
 where action >>= generator = BBind action generator
   return a = BIO (return a)

instance MonadIO Behaviour
 where liftIO action = BIO action

runBehaviour :: Behaviour a -> IO a
runBehaviour (BBind (BWaitEvent event after) f) = runBehaviour
(BWaitEvent event (after >>= f))
runBehaviour (BBind (BIO a) f) = a >>= \x -> runBehaviour (f x)
runBehaviour (BBind (BBind a f) g) = runBehaviour (a >>= (\x -> f x >>= g))
runBehaviour (BIO a) = a
runBehaviour (BWaitEvent event after) =
 do sigIdRef <- newIORef (error "You can't access sigIdRef before
signal is connected")
sigId <- event $
  do sigId <- readIORef sigIdRef
 signalDisconnect sigId
 runBehaviour after
 return ()
writeIORef sigIdRef sigId
return (error "You can't expect result from behaviour")

waitEvent :: GObjectClass obj => Event obj -> Behaviour ()
waitEvent event = BWaitEvent event (return ())

main :: IO ()
main =
  do initGUI
 window <- windowNew
 onDestroy window mainQuit
 set window [windowTitle := "Hello World"]
 button <- buttonNew
 let buttonB label =
   do liftIO $ set button [buttonLabel := label]
  waitEvent (onClicked button)
  buttonB (label ++ "*")
 runBehaviour (buttonB "*")
 set window [containerChild := button]
 widgetShowAll window
 mainGUI


-- 
Victor Nazarov
{-# LANGUAGE ExistentialQuantification #-}
module Main where

import Data.IORef
import System.Glib
import Graphics.UI.Gtk
import Control.Monad.Trans

type Event obj = IO () -> IO (ConnectId obj)

data Behaviour a =
  forall b. BBind (Behaviour b) (b -> Behaviour a)
  | BIO (IO a)
  | forall obj. GObjectClass obj => BWaitEvent (Event obj) (Behaviour a)

instance Monad Behaviour
 where action >>= generator = BBind action generator
   return a = BIO (return a)

instance MonadIO Behaviour
 where liftIO action = BIO action

runBehaviour :: Behaviour a -> IO a
runBehaviour (BBind (BWaitEvent event after) f) = runBehaviour (BWaitEvent event (after >>= f))
runBehaviour (BBind (BIO a) f) = a >>= \x -> runBehaviour (f x)
runBehaviour (BBind (BBind a f) g) = runBehaviour (a >>= (\x -> f x >>= g))
runBehaviour (BIO a) = a
runBehaviour (BWaitEvent event after) =
 do sigIdRef <- newIORef (error "You can't access sigIdRef before signal is connected")
sigId <- event $
  do sigId <- readIORef sigIdRef
 signalDisconnect sigId
 runBehaviour after
 return ()
writeIORef sigIdRef sigId
return (error "You can't expect result from behaviour")

waitEvent :: GObjectClass obj => Event obj -> Behaviour ()
waitEvent event = BWaitEvent event (return ())

main :: IO ()
main =
  do initGUI
 window <- windowNew
 onDestroy window mainQuit
 set window [windowTitle := "Hello World"]
 button <- buttonNew
 let buttonB label =
   do liftIO $ set button [buttonLabel := label]
  waitEvent (onClicked button)
  buttonB (label ++ "*")
 runBehaviour (buttonB "*")
 set window [containerChild := button]
 widgetShowAll window
 mainGUI

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


Re: [Haskell-cafe] Re: GUI programming

2010-02-03 Thread Victor Nazarov
On Wed, Feb 3, 2010 at 4:11 PM, Heinrich Apfelmus
 wrote:
> Victor Nazarov wrote:
>> data Behaviour a =
>>   forall b. BBind (Behaviour b) (b -> Behaviour a)
>>   | BIO (IO a)
>>   | forall obj. GObjectClass obj => BWaitEvent (Event obj) (Behaviour a)
>>
>> instance Monad Behaviour
>>  where action >>= generator = BBind action generator
>>        return a = BIO (return a)
>>
>> instance MonadIO Behaviour
>>  where liftIO action = BIO action
>>
>> runBehaviour :: Behaviour a -> IO a
>> runBehaviour (BBind (BWaitEvent event after) f) = runBehaviour
>> (BWaitEvent event (after >>= f))
>> runBehaviour (BBind (BIO a) f) = a >>= \x -> runBehaviour (f x)
>> runBehaviour (BBind (BBind a f) g) = runBehaviour (a >>= (\x -> f x >>= g))
>
> Just a minor note: you can somewhat clean up your code by using a
> generic monad, as implemented in my cabal package  operational
>
>   http://hackage.haskell.org/package/operational
>
> and described in
>
>   Heinrich Apfelmus. The Operational Monad Tutorial.
>   In http://themonadreader.wordpress.com/2010/01/26/issue-15/
>
>

Thank you.

It seems relevant. I'll have a look at it.

Speaking about packages. What is current community status of monad
transformers packages. I'm using MonadIO class and there are mtl,
monads-fd, monads-tf packages that provide it. I personally prefer
type families to functional dependencies. Should I use monads-tf, or
should I stick to mtl?


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


Re: [Haskell-cafe] GUI programming

2010-02-08 Thread Victor Nazarov
On Fri, Feb 5, 2010 at 9:54 PM, Mario Blažević  wrote:
> Victor Nazarov wrote:
>>
>> Hello,
>>
>> I've been writing some GUI application with Gtk2hs. It's an
>> interpreter for lambda-calculus and combinatory logic, it's GPL and if
>> you interested I can share it with cafe.
>>
>> The problem is that the GUI code has become very ugly and I'm tempted
>> to rewrite it totally. I've been looking forward to the FRP stuff, but
>> I've never seen a single definition of the term. Conal Eliot's
>> "denotational programming" is too general to be definition. I want to
>> try Grapefruit, but I got totally lost when I see arrow notation.
>>
>> I consider more lightweight and more imperative approach, something
>> closer to CSP (Communicating Secuential Processes) then FRP. I've just
>> crafted some sample program to illustrate my idea.
>>
>> The behaviour is a monad and it's IO monad so you can do any IO
>> (Gtk2hs) programming you wish. The differences is that you don't
>> attach static event handlers and tries to determine what to do
>> dependent on application state. You attach and detach handlers as much
>> as possible. Behaviour looks like a process that can stop execution
>> and wait for some GUI event. When event arrived it continues
>> execution.
>
>        To summarize, the behaviour is a suspendable IO computation. It looks
> very much like a coroutine, in fact. I'm planning to extract the
> Control.Concurrent.Coroutine module [1] into a separate package soon. It
> implements a similar concept but generalized to transform any monad and any
> functorial suspension.
>
> [1]
> http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-Coroutine.html
>
>

Yes, behaviour is exactly a coroutine. Your coroutine module seem
cool, but I would like to have a DSL closer to GUI programming than to
concurrent programming.

>> Do you see this approach viable. There are steel some details to emerge:
>> * How to wait for several events
>> * How to handle IO exceptions
>
>        I don't really know how applicable the idea is to GUI programming.
> That's not my area of expertise. I am surprised, though, that neither your
> code not your comments seem to address the issue of concurrency, as I expect
> that would be crucial in a GUI setting. Wouldn't you need different
> behaviours to run in different threads?
>

As I understand Gtk2hs still don't run in -threaded environment. And
I've been trying to avoid multithreading as much as possible. I've
already implemented exception handling through MonadError instance and
multi-event waits. Now I'm trying to rewrite GUI code of my
lambda-interpreter, and I'll publish it on hackage, when I am done.

>>
>> Here is the code:
>> {-# LANGUAGE ExistentialQuantification #-}
>> ...
>
>
>        I don't see the purpose of your BBind constructor. It seems to me
> that you could simply move the first three cases of runBehaviour
> implementation into your >>= and get rid of the constructor. Do you need
> that much laziness?
>

I think, I need it, I can't see the way to rewrite it without
intermediate data-structure. The problem is the third case:

runBehaviour (BBind (BBind a f) g) = runBehaviour (a >>= (\x -> f x >>= g))

See Heinrich Apfelmus' entry in Monad.Reader to see operational view
on monads. My implementation is very close to this idea.

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


[Haskell-cafe] Why this doesn't type checked

2010-06-27 Thread Victor Nazarov
I've allways found code like

> -- maxBound (undefined :: Int)

a bit strange as any usage of undefined is.
Being Ruby on Rails developer
I've personally found that one of the main
Rails motos is being as readable as possible.
Code must be as close to english as possible.
Embeded DSLs like rspec are made mostly to
made specs as close to english as possible.

Having this in my mind I've decided that this code should be
rewritten without undefined being mentioned. But I need some
type signature and it should mention Int type. So I've got an
idea about what I've called "fantom type functions".
So wee need type families for it to work.

> {-# LANGUAGE TypeFamilies #-}
> module Main where
>
> import Data.Word

I want the code I've mentioned to be rewrited as something like

> -- maxBound :: MaxBoundOf Int

As it is much more readable: "I want maxBound
with the type of MaxBound Of Int".

So here is the implementation of class Sizeable
that implements sizeof operation.
Which is type-indexed like maxBound is.
sizeof returns number of bytes that
occupy type when serialized to some
binary stream.

> class Sizeable sizeable
>   where type Sizeof sizeable
> sizeof :: Sizeof sizeable

We should like to make a default type
but GHC still doesn't support it.

>-- type Sizeof sizeable = Int

Instances for all basic types

> instance Sizeable Int
>   where sizeof = 4

Even without defaults we get type safety in these instances

> type Sizeof Int = Int

> instance Sizeable Word8
>   where sizeof = 1
> type Sizeof Word8 = Int
>
> instance Sizeable Word16
>   where sizeof = 2
> type Sizeof Word16 = Int
>
> instance Sizeable Word32
>   where sizeof = 4
> type Sizeof Word32 = Int
>
> instance Sizeable Word64
>   where sizeof = 8
> type Sizeof Word64 = Int

The annoyance is the need to instantiate Sizeof type family every time.
It will disappear once associated types' defaults will be implemented in GHC.

What we get with this instances is following code.

> main =
>   do print (sizeof :: Sizeof Word16)

Let's try it.

$ runhaskell this.lhs
this.lhs:78:14:
Couldn't match expected type `Int'
   against inferred type `Sizeof sizeable'
  NB: `Sizeof' is a type function, and may not be injective
In the first argument of `print', namely
`(sizeof :: Sizeof Word16)'
In the expression: print (sizeof :: Sizeof Word16)
In the expression: do { print (sizeof :: Sizeof Word16) }

What can I do with this code to make it type-check?



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


Re: [Haskell-cafe] Why this doesn't type checked

2010-06-27 Thread Victor Nazarov
On Mon, Jun 28, 2010 at 12:33 AM, Daniel Fischer
 wrote:
> On Sunday 27 June 2010 21:52:18, Victor Nazarov wrote:
>> I've allways found code like
>>
>> > -- maxBound (undefined :: Int)
>>
>> a bit strange
>
> Well, that would indeed be a bit strange since
>
> maxBound :: (Bounded a) => a
>
> and function types aren't instances of Bounded, so it'd be
>
> maxBound :: Int
> maxBound :: Char
> maxBound :: Bool
> ...
>

Yes, you are right. I've just tried to find some standard type-indexed function.
Discard everything about maxBound.

>> as any usage of undefined is.
>> Being Ruby on Rails developer
>> I've personally found that one of the main
>> Rails motos is being as readable as possible.
>
> That's good.
>
>> Code must be as close to english as possible.
>
> That not, not always, anyway. Mathematical algorithms for example tend to
> be obfuscated by englishifying.

I understand it, but RoR is trying to get as close to english as
possible as I see it.

>
>> Embeded DSLs like rspec are made mostly to
>> made specs as close to english as possible.
>>
>
>
>> What we get with this instances is following code.
>>
>> > main =
>> >   do print (sizeof :: Sizeof Word16)
>>
>> Let's try it.
>>
>> $ runhaskell this.lhs
>> this.lhs:78:14:
>>     Couldn't match expected type `Int'
>>            against inferred type `Sizeof sizeable'
>>       NB: `Sizeof' is a type function, and may not be injective
>>     In the first argument of `print', namely
>>         `(sizeof :: Sizeof Word16)'
>>     In the expression: print (sizeof :: Sizeof Word16)
>>     In the expression: do { print (sizeof :: Sizeof Word16) }
>
> Right. Since Sizeof Word8 is Int too, the type can't help determining the
> value.
>

Then it should be ambiguous type-parameter error or something like
this, why Int is expected?

>>
>> What can I do with this code to make it type-check?
>
> newtype Size a = Size { unSize :: Int }
>
> class Sizeable a where
>    sizeof :: Size a
>
> instance Sizeable Word8 where
>    sizeof = Size 1
>
> instance Sizeable Word16 where
>    sizeof = Size 2
>
> ...
>
> main = print . unSize $ sizeof :: Size Word16
>
>

Year this is good enough for me, thanx :)

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


[Haskell-cafe] Data types a la carte

2010-07-21 Thread Victor Nazarov
I've been experimenting with type level programming and open recursion.
My aim this far is to implement very modular interpreter for
lambda calculi and combinatory logic powerful enough to
demonstrate steps of some term's reduction to normal form.
I'd like to be able to setup the set of combinators
and reduction rules and to express the set in type signature.
I'd like to achieve maximum modularity of the code by all possible
means.

Below is the beginning of this effort. Show instances are defined completely
modular. Show instance for Lambda and show instance for Combinator
reuse the very same code of Show instance of ApplicativeF.
However, there are problems with this code, and
I'd like to receive some suggestions to cope with them.

1) UndecidableInstances are required for this code to compile.
Is it possible to avoid this language extension? What is the
reason for it to be required?

2) app, var, abs functions. app function is defined
differently for every example. Is it possible
to perform some automatic lifting so that app will work
for any combination of ApplicativeF? Can I use Functor class
or should I define my own type-class for this purpose? Is it
possible at all?

3) The code below uses technique similar to Data Type a la Carte.
Is it possible to achieve the same modularity using
Finally Tagless technique?

> {-# LANGUAGE TypeOperators #-}
> {-# LANGUAGE FlexibleContexts #-}
> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE UndecidableInstances #-}

Some type level combinators first

> newtype (:.) f g a = O (unO :: f (g a))
> newtype (:<*>) f g a = S {unS :: f a (g a)}
> newtype Flip f x y = Flip {unFlip :: f y x}
> newtype Mu f = Mu {unMu :: f (Mu f)}

Their show instances doesn't affect representation of
underlying type

> instance Show (f (Mu f)) => Show (Mu f)
>   where showsPrec d (Mu f) = showsPrec d f
> instance Show (f (g a)) => Show ((f :. g) a)
>   where showsPrec d (O f) = showsPrec d f
> instance Show (f a (g a)) => Show ((f :<*> g) a)
>   where showsPrec d (S f) = showsPrec d f
> instance Show (f y x) => Show (Flip f x y)
>   where showsPrec d (Flip f) = showsPrec d f

Applicative is some structure that permits application
of some objects. We use open recursion here.
ApplicativeF o is a functor that represent this structure.
And Mu (Flip ApplicativeF o) is a fix-point of this functor.

> data ApplicativeF a o = App a a | Obj o
> type Applicative o = Mu (Flip ApplicativeF o)

Pareses are left associative in applicative structure

> instance (Show o, Show a) => Show (ApplicativeF o a)
>   where showsPrec d (Obj o) = showsPrec d o
> showsPrec d (App a b) =
>   showParen (d > 4) $ showsPrec 4 a . (' ':) . showsPrec 5 b

Here is an example of applicative structure of strings

> test1 :: Applicative String
> test1 = obj "x" `app` obj "y" `app` obj "z" `app` (obj "w" `app` obj "v")
>   where obj = Mu . Obj
> app a b = Mu $ App a b

Lambda calculi is a calculi of some objects
with applicative structure. This object
may represent a variable or an abstraction of
variable. LambdaObjF encodes this fact.
We use all combinators defined above to
define objects of lambda calculi.

> data LambdaObjF name a = Var Name | Abs Name a
> type Lambda name = Mu (ApplicativeF :<*> LambdaObjF name)

> instance (Show a) => Show (LambdaObjF String a)
>   where showsPrec d (Var s) = showParen (d > 5) (showString s)
> showsPrec d (Abs s a) =
>   showParen (d > 3) $
> ('\\':) . showString s . showString ". " . showsPrec 3 a

Lets try to build an object of lambda calculi

> type Name = String

> test2 :: Lambda Name
> -- test2 = (\x. \y. x) a b
> test2 = (abs "x" (abs "y" (var "x")) `app` var "a") `app` var "b"
>   where var = Mu . S . Flip . Obj . Var
> abs x b = Mu . S . Flip . Obj $ Abs x b
> app a b = Mu . S . Flip $ App a b

Combinatory logic defines some basic combinators

> data CombinatorObjF a = CK | CS
> type Cominator = Mu (ApplicativeF :<*> CombinatorObjF)

> instance Show (CombinatorObjF a)
>   where showsPrec d CK = showString "K"
> showsPrec d CS = showString "S"

> test3 = s `app` k `app` k `app` (k `app` s)
>   where s = Mu . S . Flip . Obj $ CS
> k = Mu . S . Flip . Obj $ CK
> app a b = Mu . S . Flip $ App a b


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


Re: [Haskell-cafe] Playing with ATs again

2010-08-04 Thread Victor Nazarov
On Tue, Aug 3, 2010 at 9:45 PM, Ryan Ingram  wrote:
> So I believe the "final" way to do this, which is not yet implemented,
> works something like this:
>
> type family LeftToRight a
> type family RightToLeft b
>
> class (LeftToRight a ~ b, RightToLeft b ~ a) => Bijection a b where
>   ...
>
> I agree, the fact that this doesn't work is really dumb.
>

I think it is more simple like:

class Bijection a b where
  ...

type LeftToRight a = (Bijection a b) => b
type RightToLeft b = (Bijection a b) => a


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


Re: [Haskell-cafe] Announce: lhae

2010-09-03 Thread Victor Nazarov
On Fri, Sep 3, 2010 at 6:10 PM, abau  wrote:
> lhae is a spreadsheet program. It features a simple formula language and
> some basic statistical methods, like descriptive statistics and pivot
> tables.
>
> Other features:
> - Import from csv files
> - Export to image files
> - Export to gnuplot diagrams (currently bar charts and box plots)
> - Multilingual (english, german)
>
> Here [1] is some documentation about how to build lhae and how to use the
> formula language.
>

I was thinking about writing my own. What I wanted was adding lists
and functions (lambdas) as values.

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


Re: [Haskell-cafe] Re: Coding conventions for Haskell?

2010-09-27 Thread Victor Nazarov
On Mon, Sep 27, 2010 at 8:20 AM, Richard O'Keefe  wrote:
>
> On Sep 27, 2010, at 5:31 AM, Maciej Piechotka wrote:
>> May I ask clarification about formatting (according to your convention)
>>
>> doSomething :: (a -> a -> a) -> a -> a -> a
>> doSomething f x = f y y
>>                  where y = f x x
>>
>> i.e. single line function+where
>
> There is a meta-rule that I use for indentation in a wide range of
> languages:  where the line breaks are may depend on identifier spelling,
> but what the indentation is should not.
>
> In Haskell I sometimes violate that, but I usually end up regretting it.
>

+1

I use the same rule. My style looks like this.

module Module
  where ( FancyType (..)
, main
)

data FancyType a b
  = FirstConstructor a
  | SecondConstructor b
  deriving (Show)

f a b
  | a > 0 = FisrtConstructor a
  | otherwise = SecondConstructor g
  where g = h b
h = id

main =
  do putStrLn hello
 putStrLn . concat
   [ hello
   , show (f 25 1)
   ]
 flip mapM_ [1..100] $ \n ->
   do print n
  putStrLn hello
  where hello = "Hello"

I allways use spaces without tabs and allways use camelCase.

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


Re: [Haskell-cafe] Slightly off-topic: Lambda calculus

2009-06-21 Thread Victor Nazarov
On Sun, Jun 21, 2009 at 8:53 PM, Andrew
Coppin wrote:
> OK, so I'm guessing there might be one or two (!) people around here who
> know something about the Lambda calculus.
>
> I've written a simple interpretter that takes any valid Lambda expression
> and performs as many beta reductions as possible. When the input is first
> received, all the variables are renamed to be unique.
>
> Question: Does this guarantee that the reduction sequence will never contain
> name collisions?
>
> I have a sinking feeling that it does not. However, I can find no
> counter-example as yet. If somebody here can provide either a proof or a
> counter-example, that would be helpful.
>

It seems obvious scince beta reduction never introduces new variales...

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


Re: [Haskell-cafe] Leksah works!

2009-07-23 Thread Victor Nazarov
On Wed, Jul 1, 2009 at 1:41 AM, david48 wrote:
>
> I've build leksah from a fresh darcs get, ghc is 6.10.3 with the packages :
>
> da...@whizz:~/leksah$ ghc-pkg list
> /usr/local/lib/ghc-6.10.3/./package.conf:
>    Cabal-1.6.0.3, GLUT-2.1.1.2, HTTP-4000.0.6, HUnit-1.2.0.3,
>    OpenGL-2.2.1.1, QuickCheck-1.2.0.0, array-0.2.0.0, base-3.0.3.1,
>    base-4.1.0.0, binary-0.5.0.1, bytestring-0.9.1.4, cairo-0.10.1,
>    cgi-3001.1.7.1, containers-0.2.0.1, directory-1.0.0.3,
>    (dph-base-0.3), (dph-par-0.3), (dph-prim-interface-0.3),
>    (dph-prim-par-0.3), (dph-prim-seq-0.3), (dph-seq-0.3),
>    editline-0.2.1.0, extensible-exceptions-0.1.1.0, fgl-5.4.2.2,
>    filepath-1.1.0.2, (ghc-6.10.3), ghc-prim-0.1.0.0, gio-0.10.1,
>    glade-0.10.1, glib-0.10.1, gtk-0.10.1, gtkglext-0.10.1,
>    gtksourceview2-0.10.1, haddock-2.4.2, haskell-platform-2009.2.0.1,
>    haskell-src-1.0.1.3, haskell98-1.0.1.0, hpc-0.5.0.3, html-1.0.1.2,
>    integer-0.1.0.1, mtl-1.1.0.2, network-2.2.1, network-2.2.1.1,
>    old-locale-1.0.0.1, old-time-1.0.0.2, packedstring-0.1.0.1,
>    parallel-1.1.0.1, parsec-2.1.0.1, pretty-1.0.1.0, process-1.0.1.1,
>    random-1.0.0.1, regex-base-0.72.0.2, regex-compat-0.71.0.1,
>    regex-posix-0.72.0.3, rts-1.0, soegtk-0.10.1, stm-2.1.1.2,
>    svgcairo-0.10.1, syb-0.1.0.1, template-haskell-2.3.0.1,
>    time-1.1.2.4, time-1.1.3, unix-2.3.2.0, utf8-string-0.3.5,
>    xhtml-3000.2.0.1, zlib-0.5.0.0
> da...@whizz:~/leksah$
>
>
> The OS is Kubuntu Jaunty (9.04) and GTK comes from the Jaunty repositories.
>
I can't build leksah: I've got:

src/IDE/Completion.hs:99:26-59:
Not in scope: `sourceLanguageManagerGuessLanguage'
cabal: Error: some packages failed to install:
leksah-0.6.1 failed during the building phase. The exception was:
exit: ExitFailure 1

I have:
$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 6.10.4

$ ghc-pkg list
/usr/local/lib/ghc-6.10.4/./package.conf:
Cabal-1.6.0.1, Cabal-1.6.0.3, HTTP-4000.0.7, HUnit-1.2.0.3,
QuickCheck-1.2.0.0, array-0.2.0.0, base-3.0.3.1, base-4.1.0.0,
binary-0.5.0.1, bytestring-0.9.1.4, cairo-0.10.1,
containers-0.2.0.1, directory-1.0.0.3, (dph-base-0.3),
(dph-par-0.3), (dph-prim-interface-0.3), (dph-prim-par-0.3),
(dph-prim-seq-0.3), (dph-seq-0.3), extensible-exceptions-0.1.1.0,
filepath-1.1.0.2, gconf-0.10.1, (ghc-6.10.4), ghc-prim-0.1.0.0,
gio-0.10.1, glade-0.10.1, glib-0.10.1, gnomevfs-0.10.1,
gstreamer-0.10.1, gtk-0.10.1, gtkglext-0.10.1,
gtksourceview2-0.10.1, haddock-2.4.2, haskell-src-1.0.1.3,
haskell98-1.0.1.0, hpc-0.5.0.3, html-1.0.1.2, integer-0.1.0.1,
mtl-1.1.0.2, network-2.2.1.2, old-locale-1.0.0.1, old-time-1.0.0.2,
packedstring-0.1.0.1, parallel-1.1.0.1, parsec-2.1.0.1,
pretty-1.0.1.0, process-1.0.1.1, random-1.0.0.1,
regex-base-0.72.0.2, regex-compat-0.71.0.1, regex-posix-0.72.0.3,
rts-1.0, soegtk-0.10.1, stm-2.1.1.2, svgcairo-0.10.1, syb-0.1.0.1,
template-haskell-2.3.0.1, time-1.1.4, unix-2.3.2.0,
utf8-string-0.3.5, xhtml-3000.2.0.1, zlib-0.5.2.0
/home/vir/.ghc/i386-linux-6.10.4/package.conf:
Cabal-1.6.0.1, Cabal-1.6.0.3, binary-0.5.0.1, utf8-string-0.3.5


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


[Haskell-cafe] FastCGI error handling

2009-08-03 Thread Victor Nazarov
I've been trying to write some simple web application in haskell using
FastCGI, HDBC and HStringTemplate. I've got stuck with the following
problem.

HDBC throws some exceptions and I wanted them to be caught and logged.
The code was:

-- Main.hs
module Main (main) where

...
import Control.Concurrent
import Network.FastCGI

driver :: CGI CGIResult
driver = ...

main :: IO ()
main = runFastCGIConcurrent' forkIO 10 (handleErrors test)

But all I've got on the page and in the log is "SomeException" string.

I've tried the workaround:
-- Main.hs
module Main (main) where

import Network.FastCGI
import Control.Exception
import System.IO

driver :: CGI CGIResult
driver = ...

...
main :: IO ()
main = runFastCGI driver `catch` \ex -> hPutStr stderr $ show
(ex::SomeException)

And this worked fine. I've got a detaied SqlException string in the log file.

So I've decided to update exception handling in CGI package and
written the following module:

-- Network/CGI/Monad/NewException.hs
module Network.CGI.Monad.NewException where

import Prelude hiding (catch)

import Control.Exception
import Control.Monad
import Control.Monad.Writer
import Control.Monad.Reader

import Network.CGI.Monad hiding (throwCGI, catchCGI, tryCGI)
import Network.CGI (outputInternalServerError)

-- | Throw an exception in a CGI monad. The monad is required to be
--   a 'MonadIO', so that we can use 'throwIO' to guarantee ordering.
throwCGI :: (MonadCGI m, MonadIO m, Exception e) => e -> m a
throwCGI = liftIO . throwIO

-- | Catches any expection thrown by a CGI action, and uses the given
--   exception handler if an exception is thrown.
catchCGI :: (Exception e) => CGI a -> (e -> CGI a) -> CGI a
catchCGI c h = tryCGI c >>= either h return

handleCGI :: (Exception e) => (e -> CGI a) -> CGI a -> CGI a
handleCGI = flip catchCGI

-- | Catches any exception thrown by an CGI action, and returns either
--   the exception, or if no exception was raised, the result of the action.
tryCGI :: (Exception e) => CGI a -> CGI (Either e a)
tryCGI (CGIT c) = CGIT (ReaderT (\r -> WriterT (f (runWriterT
(runReaderT c r)
where
  f = liftM (either (\ex -> (Left ex,mempty)) (\(a,w) -> (Right a,w))) . try

handleErrors = handleCGI outputException

outputException e = outputInternalServerError [show (e :: SomeException)]

Then I've updated Main.hs accordingly:

module Main (main) where

...
import Control.Concurrent
import Network.FastCGI hiding (throwCGI, catchCGI, tryCGI,
handleErrors, outputException)
import Network.CGI.Monad.NewException

driver :: CGI CGIResult
driver = ...

main :: IO ()
-- main = runFastCGIConcurrent' forkIO 10 (handleErrors test) -- This
allways gives internal error without a chance to find out what happens
main = runFastCGI $ handleErrors test -- This works fine

So one variant of main function works, the other allways gives no
output. What can be the case?

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


[Haskell-cafe] Re: FastCGI error handling

2009-08-03 Thread Victor Nazarov
On Mon, Aug 3, 2009 at 4:32 PM, Victor Nazarov wrote:
> I've been trying to write some simple web application in haskell using
> FastCGI, HDBC and HStringTemplate. I've got stuck with the following
> problem.
>
[snip]
>
> main :: IO ()
> -- main = runFastCGIConcurrent' forkIO 10 (handleErrors test) -- This
> allways gives internal error without a chance to find out what happens
> main = runFastCGI $ handleErrors test -- This works fine
>
> So one variant of main function works, the other allways gives no
> output. What can be the case?
>

The problem seems to be GHC's -threaded flag. Everything works fine
with this flag.

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


[Haskell-cafe] Problem with type families

2009-09-21 Thread Victor Nazarov
I've tried to reimplement code presented in the following blog post:
http://cdsmith.wordpress.com/2009/09/20/side-computations-via-type-classes/

But I've got stuck with the following error:

Triangulable.hs:41:8:
`addRows' is not a (visible) method of class `Triangulable'

Triangulable.hs:43:8:
`addCols' is not a (visible) method of class `Triangulable'

I think the minimal example to reproduce this error is the following:

...
class Triangulable m
  where type Elem m
(@@) :: m -> (Int, Int) -> Elem
size :: m -> Int
swapRows :: Int -> Int -> m -> m
swapCols :: Int -> Int -> m -> m
addRow   :: (Num Elem) => Elem -> Int -> Int -> m -> m
addCol   :: (Num Elem) => Elem -> Int -> Int -> m -> m

newtype ListMatrix a = ListMatrix [[a]]

instance Num a => Triangulable (ListMatrix a)
  where type Elem (ListMatrix a) = a
(ListMatrix xs) @@ (i, j) = xs !! i !! j
size (ListMatrix xs) = size xs
swapRows m n (ListMatrix xs) = ListMatrix $ swap m n xs
swapCols m n (ListMatrix xs) = ListMatrix $ map (swap m n) xs
addRows q m n (ListMatrix xs) = ListMatrix $ modifyNth n
(zipWith comb (xs !! m))
  where comb a b = q * a + b
addCols q m n (LisMatrix xs) = ListMatrix $ map (\row ->
modifyNth n (comb (row !! m)) row)
  where comb a b = q * a + b
...

How can I fix this?

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


Re: [Haskell-cafe] Problem with type families

2009-09-21 Thread Victor Nazarov
On Tue, Sep 22, 2009 at 1:31 AM, Daniel Fischer
 wrote:
> Am Montag 21 September 2009 23:15:48 schrieb Victor Nazarov:
>> I've tried to reimplement code presented in the following blog post:
>> http://cdsmith.wordpress.com/2009/09/20/side-computations-via-type-classes/
>>
>> But I've got stuck with the following error:
>>
>> Triangulable.hs:41:8:
>>     `addRows' is not a (visible) method of class `Triangulable'
>>
>> Triangulable.hs:43:8:
>>     `addCols' is not a (visible) method of class `Triangulable'
>>
>> I think the minimal example to reproduce this error is the following:
>>
>> ...
>> class Triangulable m
>>   where type Elem m
>>         (@@)     :: m -> (Int, Int) -> Elem
>>         size     :: m -> Int
>>         swapRows :: Int -> Int -> m -> m
>>         swapCols :: Int -> Int -> m -> m
>>         addRow   :: (Num Elem) => Elem -> Int -> Int -> m -> m
>>         addCol   :: (Num Elem) => Elem -> Int -> Int -> m -> m
>>
>> newtype ListMatrix a = ListMatrix [[a]]
>>
>> instance Num a => Triangulable (ListMatrix a)
>>   where type Elem (ListMatrix a) = a
>>         (ListMatrix xs) @@ (i, j) = xs !! i !! j
>>         size (ListMatrix xs) = size xs
>>         swapRows m n (ListMatrix xs) = ListMatrix $ swap m n xs
>>         swapCols m n (ListMatrix xs) = ListMatrix $ map (swap m n) xs
>>         addRows q m n (ListMatrix xs) = ListMatrix $ modifyNth n
>> (zipWith comb (xs !! m))
>>           where comb a b = q * a + b
>>         addCols q m n (LisMatrix xs) = ListMatrix $ map (\row ->
>> modifyNth n (comb (row !! m)) row)
>>           where comb a b = q * a + b
>> ...
>>
>> How can I fix this?
>
> Shouldn't the methods be called the same in the class definition and instance 
> declaration?
>
> So
>
> instance ...
>    where
>   ...
>    addRow q m n (ListMatrix xs) = ...
>    addCol q m n (ListMatrix xs) = ..
>

Yes that's right. My fault, I was too conserned with Fractional
context in addRow and addCol function that I failed to see a simple
bug.

Here is working code for those who is interested:
http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=9676#a9676

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


[Haskell-cafe] Haskell guards

2007-09-20 Thread Victor Nazarov
I still can't remember how guards are treated in Haskell. Here is the
code snippet in question:

foo a | a == 1 = 6
foo a | a == 2 = 7
foo a = 8

Would Haskell fall through to the third alternative if a is not equal
to 1 or 2. I know that this can be rewritten more sanely, but I just
consider guard behavior. What would be the value of (foo 3)?

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


Re: [Haskell-cafe] distghc possible?

2007-09-27 Thread Victor Nazarov
> i am a newbie in haskell.
> i have read about the tool distcc, http://distcc.samba.org/.
> so i was wondering, does something like this already exist for
> haskell?
> would it be possible to implement a similar tool based on ghc for
> haskell or does this not make sense as a haskell program has to be
> compiled all in one go?
> how are haskell programs compiled?
> it would be great if someone would have some suggestions on this.

It seems possible and you can use ghc as a compiler on each machine
from the compilation farm. I think distcc can be accommodated to do
it.

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


Re: [Haskell-cafe] Why not assign a type to unsafePerformIO?

2007-10-03 Thread Victor Nazarov
On 10/4/07, Justin Bailey <[EMAIL PROTECTED]> wrote:
> On 10/3/07, Victor Nazarov <[EMAIL PROTECTED]> wrote:
> > But how would you know that evil dictator uses unsafePerformIO???
>
> You don't. unsafePerformIO  can't be taken it away (there are legitimate
> reasons to strip IO), which is why I wonder if it's useful at all.
>
> p.s. CC'ed to haskell-cafe
>

May be you should be interested in Tom Mortel's example of using
unsafeInterleaveIO:
http://blog.moertel.com/articles/2007/03/28/directory-tree-printing-in-haskell-part-three-lazy-i-o

If you don't mean anything like this, I don't understand your intent.

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


Re: [Haskell-cafe] Re: distinguish functions from non-functions in a class/instances

2007-12-07 Thread Victor Nazarov
On Dec 7, 2007 4:46 PM, Luke Palmer <[EMAIL PROTECTED]> wrote:
> On Dec 7, 2007 6:27 AM, Victor Nazarov <[EMAIL PROTECTED]> wrote:
> >
> > nary 0 x [] = x
> > nary n f (x:xs) | n > 0 = nary (n-1) (f $ read x) xs
>
> Sometimes it helps to write type signatures for functions.  As in this
> case, where you'll find you won't be able to...  :-)
>
> Luke
>

Ok :)

> {-# OPTIONS -fglasgow-exts #-}
> {-# OPTIONS -fallow-undecidable-instances #-}

data Zero
data Succ a

class Nary n x y | n x -> y where
  nary :: n -> x -> [String] -> y

instance Nary Zero x x where
  nary _ x [] = x

instance (Nary n y z, Read x) => Nary (Succ n) (x->y) z where
  nary _ f (x:xs) = nary (undefined::n) (f $ read x) xs

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


Re: [Haskell-cafe] Re: distinguish functions from non-functions in a class/instances

2007-12-07 Thread Victor Nazarov
On Dec 7, 2007 2:52 PM,  <[EMAIL PROTECTED]> wrote:
>
> In fact, that distinction is possible. The following article
>
> How to write an instance for not-a-function
> http://okmij.org/ftp/Haskell/typecast.html#is-function-type
>
> specifically describes a method of writing an instance which is
> selected only when the type in question is NOT a function. The method
> is quite general and has been extensively used (for example, to
> implement deep monadic join).
>

Cool solution and not so complicated and ad-hoc. But I'd like to ask
isn't the following definition is more natural and simple?

nary 0 x [] = x
nary n f (x:xs) | n > 0 = nary (n-1) (f $ read x) xs

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


[Haskell-cafe] Displaying steps in my interpreter

2008-01-10 Thread Victor Nazarov
Hello,
I have little practice in Haskell. And I look forward for suggestions on how
to improve the code. Code is not working: some definitions are missed.

The goal of the code is to implement the evaluator for untyped lambda-calculus.
The main problem is how to display each step of reduction? More
detailed questions follows in the end of the code.

Terms of lambda-calculus is the following data-type:
>
> data (Binder bndr) =>
>   Term bndr =
> Var bndr
> | Lam bndr (Term bndr)
> | App (Term bndr) (Term bndr)
>

Binder class is used to generate new unique binders and to compare binders
>
> class (Eq bndr) => Binder bndr
>   where {- ... -}
>

Next we'll define the evaluator. Evaluator returns the WHNF for each
well-formed term, or _|_ if there is no WHNF

Straight forward version:

whnf :: Term bndr -> Term bndr
whnf = reduce []
 where reduce (a:as) (Lam b i) = reduce as $ subst b a i
   reduce as (App f a) = reduce (a:as) f
   reduce as term = foldl term App as

But our goal is to perform only one step of reduction. And to display term
after each reduction

We refactor the original definition to perform this:

>
> whnfGen :: (Maybe String -> Bool) -> Term bndr -> Term bndr
> whnfGen isFinal = runSteps isFinal $ reduce' []
>
>   where reduce' (a:as) (Lam b i) = markStep "beta" >> reduce as $ subst b a i
> reduce' as (App f a) = reduce (a:as) f
> reduce' as term = unwind as term
>
> reduce as term =
>   do final <- checkFinal
>  if final
>then unwind as term
>else reduce' as term
>
> unwind as term = return $ foldl term App as
>

Steps is the monad:

>
> newtype Steps mark a =
>  Steps { unSteps :: StateT (Maybe mark) (Reader (Maybe mark -> Bool)) a }
>
> instance Monad (Steps mark)
>  where (Steps a) >>= f = Steps $ a >>= \x -> unSteps (f x)
>   return a = Steps $ return a
>
> runSteps :: (Maybe mark -> Bool) -> Steps a -> (Maybe mark, a)
> runSteps isFinal act = runReader (runStateT (unSteps act) Nothing) isFinal
>
> checkFinal :: Steps mark Bool
> checkFinal =
>   do st <- Steps $ get
>  isFinal <- Steps $ lift $ ask
>  return $ isFinal st
>
> markStep :: mark -> Steps mark ()
> markStep = Steps . put . Just
>

Normal whnf can be written as follows:

>
> whnf = whnfGen (const False)
>

To print the reduction steps we can use the following code

>
> printReductions t =
>   do t' <- whnfGen isJust t
>  print t'
>  printReductions t'
>

Is there any better ways to implement printReductions? Is there a way to
abstract out this steps pattern? For example if I want to show the process
of converting lambda-terms to combinatory logic terms (I, K, S basis).
I'll have to implement the same pattern. I can reuse Steps monad, but, I'll
have to use markStep, checkFinal and special version of recursion. Is there
a way to abstract this?

Is there a more effective way to perform this? In printReductions I have
to rescan the syntax tree over and over again to find the redex. Is there a
way to save the position in the tree, to print the tree and then to resume
from saved position?

Thanx for reading this :)
-- 
vir
http://vir.comtv.ru/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] \_ -> not equivalent to const $

2008-01-10 Thread Victor Nazarov
On Jan 11, 2008 2:11 AM, Felipe Lessa <[EMAIL PROTECTED]> wrote:
> On Jan 10, 2008 8:54 PM, Luke Palmer <[EMAIL PROTECTED]> wrote:
> > Can someone explain what the heck is going on here?
>
> AFAICT, nothing is wrong. You see, both returned the very same values.
[snip]
> But referential transparency wasn't broken at all =).
>
Referential transparency wasn't broken, but I wonder what was the
compiler, and what were it's options.

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


Re: [Haskell-cafe] \_ -> not equivalent to const $

2008-01-10 Thread Victor Nazarov
On Jan 11, 2008 2:28 AM, Felipe Lessa <[EMAIL PROTECTED]> wrote:
> On Jan 10, 2008 9:20 PM, Luke Palmer <[EMAIL PROTECTED]> wrote:
> > Ahh, it was ghc 6.8.1, without any optimization.  If I turn on optimization,
> > the behavior goes away, and they both behave like the const version.
>
> That was what I suggested on the last line of my previous e-mail. As
> const is in Prelude, which probably was compiled with optimizations,
> it would explain the difference.

Optimization of const doesn't affect this program behavior.

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


Re: [Haskell-cafe] Re: Displaying steps in my interpreter

2008-01-11 Thread Victor Nazarov
On Jan 10, 2008 8:39 PM, apfelmus <[EMAIL PROTECTED]> wrote:
> Victor Nazarov wrote:
> >
> Yes, there is: you can use a zipper
>
>http://en.wikibooks.org/wiki/Haskell/Zippers
>
> Here's how:
>
>data Branch v = AppL (Term v)
>  | AppR (Term v)
>  | Lamb v
>type Context v = [Branch v]
>type Zipper v  = (Context v, Term v)
>
>unwind :: Zipper v -> Term v
>unwind ([], t) = t
>unwind (AppL e:cxt, f) = unwind (cxt, App f e)
>unwind (AppR f:cxt, e) = unwind (cxt, App f e)
>unwind (Lamb x:cxt, e) = unwind (cxt, Lam x e)
>

Thanks. Zippers seemed very cool when I first encountered them in some
text about xmonad. But I've never used them in my own code.

> Concerning the problem of printing intermediate steps, I don't quite
> understand your approach. I'd simply use a Writer monad to keep track of
> intermediate terms
>

My version just return when the state in State monad is not Nothing,
so we can print result and start over again.

>import Control.Monad.Writer
>
>   -- use a difference list or something for better performance
>type Trace v = [Zipper v]
>
>whnf :: Term v -> Writer (Trace v) (Term v)
>whnf t = whnf' ([],t)
>   where
>   whnf' (AppL e':cxt, Lam x e) = tell  (cxt, App (Lam x e) e') >>
>  whnf' (cxt   , subst x e' e)
>   whnf' (cxt, App f e) = whnf' (AppL e:cxt, f)
>   whnf' z  = return $ unwind z
>
> The definition of  whnf  is basically left unchanged, except that a
> redex is recorded via  tell  whenever a beta-reduction is about to be
> performed. The recorded terms can be printed afterwards
>
>printTrace :: Writer (Trace v) (Term v) -> IO ()
>printTrace w = let (t, ts) = runWriter t ts
>  putStrLn . unlines . map show $ ts
>

Is this function lazy? Can I run this code on term without nf and
print n-first steps:

>printTraceN :: Int -> Writer (Trace v) (Term v) -> IO ()
>printTraceN n w =
>  let (t, ts) = runWriter t ts
>  in putStrLn . unlines . map show $ take n ts
>

Will this work:

> printTraceN 5 (read "(\x. x x x) (\x. x x x)")

?

>
> Last but not least, there is a nice introductory paper about the many
> possible reduction strategies for lambda calculus
>
>http://www.itu.dk/people/sestoft/papers/sestoft-lamreduce.pdf
>

Thank you.

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


Re: Re[2]: The programming language market (was Re: [Haskell-cafe] Why functional programming matters

2008-01-27 Thread Victor Nazarov
On Jan 27, 2008 11:49 AM, Bulat Ziganshin <[EMAIL PROTECTED]> wrote:
> oh, yes, they are really still study 19th century physics, but not
> because of great mind, but due to age of university professors. i've
> studied at Moscow University in 89-91 and department of computer
> languages still studied Lisp at those times (!). a few months ago i
> have a conversation with today student and they still learn Lisp (!!!).
> it seems that they will switch to more modern FP languages no earlier
> that this concrete professor, head of PL department, which in 60s done
> interesting AI research, will dead, or at least go to the pension
>
I've learned Haskell in MEPhI. And Lisp seems to be really popular now
due to Paul Graham.

What I really want to mention is that the philosophy of education in
Russia consider "modern" irrelevant. "Modern" changes really fast and
it is not any better to teach something modern then outdated, except
if you are going to create some ballast of Java programmers who will
prevent progress and preserve market stability, i. e. really be
outdated. What university try to do is teach you how to swim really
good, so you'll have a better chances to find out where to swim. I
mean they teach you to learn, not anything else. Everything else is
just a pretty bonus.

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


Re: [Haskell-cafe] Re: Datatypes - Haskell

2008-02-10 Thread Victor Nazarov
On Feb 10, 2008 3:40 PM, Mattes Simeon <[EMAIL PROTECTED]> wrote:
> Thanks for your help. It was very useful.
>
> Though in comparison with C or C++ I can't figure out so clear the syntax.
> Maybe it has to do with the syntactic Sugar of each Language. I 'll give you a
> similar example I saw in a book for Haskel
>
> The following program just returns the value of the position of a datatype 
> Tuple
> which can hold one or two elements.
>
> data Tuple a b = One a | Two a b
> tuple1 (One a)= Just a
> tuple1 (Two a b) = Just a
>
> tuple2 (One a) = Nothing
> tuple2 (Two a b) = Just b
>
> The corresponding Version in C++, which seems to be more appropriate, would be

I think this is the most native way to do it in C++:
template 
class Tuple {
public:
static Tuple *One (A *a) { return new One (a); }
static Tuple *Two (A *a, B *b) { return new Two (a, b); }
virtual A *tuple1 () = 0;
virtual B *tuple2 () = 0;
};

template 
class One : Tuple
{
public:
  One (A *a) { this->a = a; }
  A *tuple1 () { return a; }
  B *tuple2 () { return NULL; }
private:
  A *a;
}

template 
class Two: Tuple
{
public:
  Two (A *a, B *b) { this->a = a; this->b = b}
  A *tuple1 () { return a; }
  B *tuple2 () { return b; }
private:
  A *a;
  B *b;
}



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