Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Exercise of "Programming with Arrows" (Thiago Negri)
   2.  Error when starting GHCI (Arie van Wingerden)


----------------------------------------------------------------------

Message: 1
Date: Tue, 8 Oct 2013 12:43:04 -0300
From: Thiago Negri <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Exercise of "Programming with Arrows"
Message-ID:
        <CABLneZuicJGnm8KV=bl-jeluaosjcw+9z8vs9k6wuhwd3xd...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

I think I'm starting to get the "way of arrows".

My implementation was incorrect. I've seen it with the hand made test
listed below [1].
The output of "first arrA" and "first arrB" should be joined together and
form a new stream with the length of the shortest output of both ("arrA ***
arrB"), and this wasn't happening.

I've found package "streamproc" at Hackage and that gave me some insights.
Yet I think "streamproc" is also wrong, as it does not buffer the second
stream.
You can check it at line 58 of SP.hs [3] that it ignores the first element
of the pair.
But I didn't write a test to check what is the implication of this, I'll
try to do this as a next step into understanding arrows.

That exercise really helped me!

My new implementation, wich I think is correct now, is listed below [2].

Thanks!

Thiago


[1]:
inputA :: [String]
inputA = ["a", "b", "hello", "c", "d", "e", "hello", "f", "g", "e", "x"]

arrA :: SP String String
arrA = Get (\a -> if a == "hello" then (Put a (Put "world" arrA))
                                  else (Put "unknown" arrA))

arrB :: SP String String
arrB = Get (\a -> if a == "my" then (Get (\a -> if a == "name" then (Get
(\a -> if a == "is" then Get (\a -> Put ("name: " ++ a) arrB)

                 else arrB))
                                                               else arrB))
                               else arrB)

inputB :: [String]
inputB = ["a", "b", "my", "name", "is", "thiago", "and", "I", "am", "so",
"cool"]

inputAB :: [(String, String)]
inputAB = zip inputA inputB

main :: IO ()
main = let actualOutputB = runSP arrB inputB
           actualOutputB1 = runSP (first arrB) (zip inputB (repeat "a"))
           actualOutputA = runSP arrA inputA
           actualOutputA1 = runSP (first arrA) (zip inputA (repeat "a"))
           actualOutputAB = runSP (arrA *** arrB) inputAB
       in do putStrLn $ "inputAB: " ++ show inputAB
             putStrLn $ "outputA: " ++ show actualOutputA
             putStrLn $ "outputA1: " ++ show actualOutputA1
             putStrLn $ "outputB: " ++ show actualOutputB
             putStrLn $ "outputB1: " ++ show actualOutputB1
             putStrLn $ "outputAB: " ++ show actualOutputAB



[2]:
module SP where

import Prelude hiding (id, (.))
import Control.Category
import Control.Arrow
import Test.QuickCheck

data SP a b = Put b (SP a b) | Get (a -> SP a b)

runSP :: SP a b -> [a] -> [b]
runSP (Put b s) as = b:runSP s as
runSP (Get k) (a:as) = runSP (k a) as
runSP (Get k) [] = []

compose :: SP b c -> SP a b -> SP a c
compose (Put a s) g = Put a (compose s g)
compose (Get k) (Put a s) = compose (k a) s
compose f (Get k) = Get (\a -> compose f (k a))

instance Category SP where
  id = arr id
  (.) = compose

instance Arrow SP where
  arr f = Get (\a -> Put (f a) (arr f))
  first = queued empty empty

queued :: Queue a -> Queue c -> SP a b -> SP (a, c) (b, c)
queued qa qc (Put a s) = case pop qc of Nothing -> Get (\(a', c) -> Put (a,
c) (queued (push a' qa) qc s))
                                        Just (c, qc') -> Put (a, c) (queued
qa qc' s)
queued qa qc (Get k) = case pop qa of Nothing -> Get (\(a, c) -> queued qa
(push c qc) (k a))
                                      Just (a, qa') -> queued qa' qc (k a)

data Queue a = Queue [a]

empty :: Queue a
empty = Queue []

push :: a -> Queue a -> Queue a
push a (Queue as) = Queue (a:as)

pop :: Queue a -> Maybe (a, Queue a)
pop (Queue []) = Nothing
pop (Queue (a:as)) = Just (a, Queue as)

delayed :: (a, c) -> SP a b -> SP (a, c) (b, c)
delayed (a, c) (Put b s) = Put (b, c) (delayed (a, c) s)
delayed (a, c) (Get k) = firstWithValue (k a) c

firstWithValue :: SP a b -> c -> SP (a, c) (b, c)
firstWithValue (Put a s) c = Put (a, c) (firstWithValue s c)
firstWithValue (Get k) _ = Get (\(a, c) -> firstWithValue (k a) c)

input :: [(String, String)]
input = [("a1", "a2"), ("b1", "b2"), ("c1", "c2"), ("d1", "d2")]

myArrow :: SP (String, String) (String, String)
myArrow = (delay "db1" >>> delay "da1") *** (delay "db2" >>> delay "da2")

delay :: a -> SP a a
delay b = Put b (arr id)

inputA :: [String]
inputA = ["a", "b", "hello", "c", "d", "e", "hello", "f", "g", "e", "x"]

arrA :: SP String String
arrA = Get (\a -> if a == "hello" then (Put a (Put "world" arrA))
                                  else (Put "unknown" arrA))

arrB :: SP String String
arrB = Get (\a -> if a == "my" then (Get (\a -> if a == "name" then (Get
(\a -> if a == "is" then Get (\a -> Put ("name: " ++ a) arrB)

                 else arrB))
                                                               else arrB))
                               else arrB)

inputB :: [String]
inputB = ["a", "b", "my", "name", "is", "thiago", "and", "I", "am", "so",
"cool"]

inputAB :: [(String, String)]
inputAB = zip inputA inputB

main :: IO ()
main = let actualOutputB = runSP arrB inputB
           actualOutputB1 = runSP (first arrB) (zip inputB (repeat "a"))
           actualOutputA = runSP arrA inputA
           actualOutputA1 = runSP (first arrA) (zip inputA (repeat "a"))
           actualOutputAB = runSP (arrA *** arrB) inputAB
       in do putStrLn $ "inputAB: " ++ show inputAB
             putStrLn $ "outputA: " ++ show actualOutputA
             putStrLn $ "outputA1: " ++ show actualOutputA1
             putStrLn $ "outputB: " ++ show actualOutputB
             putStrLn $ "outputB1: " ++ show actualOutputB1
             putStrLn $ "outputAB: " ++ show actualOutputAB



[3]: https://github.com/peti/streamproc/blob/master/Control/Arrow/SP.hs#L58


2013/10/7 Thiago Negri <[email protected]>

> This is my first contact with QuickCheck, but does this test count as a
> proof that my implementation is correct?
>
> QuickCheck shows 100 tests passed.
>
> prop_a xs = runSP (f *** g) xs == runSP (first f >>> swap >>> first g >>>
> swap) xs
>   where swap = arr (\(a,b) -> (b,a))
>         f = arr (++"a")
>         g = arr (++"b")
>
>
>
> 2013/10/7 Thiago Negri <[email protected]>
>
>> "On the one hand, indeterminate a's need to be fed in before
>> indeterminate b's get pulled out. On the other hand, the c's need to behave
>> as if they were in a no-op assembly line. One c goes in, the one (and
>> same!) c drops out."
>>
>> I agree with "no-op assembly line", but when I'm using `first` on a
>> processor, I want to process the first stream *only*. The second stream
>> should remain as it was not touched, so future processors will receive the
>> same sequence from the second stream.
>>
>> I mean, I think I need to guarantee that this definition holds:
>>
>> `g *** f` is the same as `first g >>> swap >>> first f >>> swap`
>>
>> If my implementation of `first` uses a real no-op assembly line for `c`
>> (i.e., `arr id`), then I would lose the stream. As you said, I need to
>> buffer the second stream while processing the first one.
>>
>> Is my line of tought correct?
>>
>> I'll try to write some tests to verify this.
>>
>> Thanks!
>>
>>
>> 2013/10/7 Kim-Ee Yeoh <[email protected]>
>>
>>> Hey Thiago,
>>>
>>> First of all, congratulations for reading Hughes! Many of his papers are
>>> worth reading and re-reading for both beginners and experts alike.
>>>
>>>
>>> On Tue, Oct 8, 2013 at 12:05 AM, Thiago Negri <[email protected]> wrote:
>>>
>>>> Exercise 2 (section 2.5) is asking to create a Stream Processor that
>>>> can map more than one output per input (e.g. 3 outcomes for a single
>>>> consume of the stream).
>>>
>>>
>>> Given
>>>
>>>
>>> > data SP a b = Put b (SP a b) | Get (a -> SP a b)
>>>
>>> it's easy to see that it's not just about more than one output per
>>> input. It's about n pieces of input producing m pieces of output, where
>>> (n,m) may even -- and probably does -- depend on previous inputs!
>>>
>>> The exercise asks for an implementation of the following Arrow instance:
>>>
>>> > first :: arr a b -> arr (a,c) (b,c)
>>>
>>> which, specialized to our case, is just SP a b -> SP (a,c) (b,c).
>>>
>>> It should now be apparent what the 'trickiness' is. On the one hand,
>>> indeterminate a's need to be fed in before indeterminate b's get pulled
>>> out. On the other hand, the c's need to behave as if they were in a no-op
>>> assembly line. One c goes in, the one (and same!) c drops out.
>>>
>>> So one way to look at this is as a buffering problem.
>>>
>>> At this point, I'd encourage you to think of some quickcheck tests you
>>> can write to convince yourself whether you have a right implementation or
>>> not.
>>>
>>> Your main function doesn't seem adequate for the task.
>>>
>>> -- Kim-Ee
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> [email protected]
>>> http://www.haskell.org/mailman/listinfo/beginners
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20131008/a6fb6264/attachment-0001.html>

------------------------------

Message: 2
Date: Tue, 8 Oct 2013 18:12:41 +0200
From: Arie van Wingerden <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] Error when starting GHCI
Message-ID:
        <CADkALSHpG7s89tT7rXJw56q7hkDyEcwv1=xu5tg3_qlqoqt...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

Hi,

today I downloaded the Haskell platform for 32 bits Windows
(HaskellPlatform-2013.2.0.0-setup.exe) and installed it.

The first time I started GHCI all worked perfectly.

When I closed GHCI and later tried to start it again I constantly get
however:
C:\Users\Arie>ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... ghc.exe: : Kan opgegeven module niet vinden.
<command line>: can't load .so/.DLL for:  (addDLL: could not load DLL)
WHERE Kan opgegeven module niet vinden MEANS Can't find the specified module

Any ideas?

Kind regards,
   Arie
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20131008/8f467084/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 64, Issue 13
*****************************************

Reply via email to