- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]

From: Michael Hanus <mh_at_informatik.uni-kiel.de>

Date: Mon, 07 Dec 2015 16:48:12 +0100

Hi,

just a short comment. I think the reason why your example works

is not due to the features of Curry but due to the unintended use

of some features. The non-strict unification operator (=:<=)

is intended to implement functional patterns, i.e., a rule like

last (_++[x]) = x

is transformed into

last xs | _++[x] =:<= xs =x where x free

in order to implement the intended semantics of functional patterns.

As an invariant, the second argument is always a variable denoting

some actual argument. Without this invariant, as in your fib example,

I don't see some declarative meaning of this operator (at least,

it has not be explored).

Best regards,

Michael

On 12/04/2015 09:04 AM, Sebastian Hanowski wrote:

*>
*

*> Hi all,
*

*>
*

*>
*

*> Haskell sometimes get's critisized for collapsing the notion of finite
*

*> and infinite data because the latter should be opaque like functions
*

*> or that it requires you to mention lazy evaluation when explaining
*

*> non-terminating recursive definitions.
*

*>
*

*> Applying the same critique to Curry seems somehow unfair since it
*

*> already contains a remedy!
*

*>
*

*> Instead of writing for example the fibonaci sequence in terms of
*

*> constructors and self reference
*

*>
*

*> -- fib = 1 : 1 : zipWith (+) fib (tail fib)
*

*>
*

*> Curry alternativly let's you define it this way
*

*>
*

*> fib | head x =:<= 1
*

*> & head (tail x) =:<= 1
*

*> & tail (tail x) =:<= zipWith (+) x (tail x) = x where x free
*

*>
*

*> Since we know now that it's possible to define the program without
*

*> having to mention constructors, the next step would be to completely
*

*> hide the concrete representation in a module with only the selection
*

*> functions being exported.
*

*>
*

*> module Stream(Stream,sHead,sTail) where ...
*

*>
*

*> However since the fibonacci sequence is my running example please allow=
*

*> that we assume this as already working, induct on this and proceed
*

*> directly to the next next step by combining both previous results ;)
*

*>
*

*> If we seal a definition of an infinite data structure in a module
*

*> aliasing it's constructor with a defined function e. g. by saving the
*

*> following to a file
*

*>
*

*> module Stream(Stream,(>:)) where
*

*>
*

*> data Stream a = SCons a (Stream a)
*

*>
*

*> infix r 5
*

*> (>:) :: a -> Stream a -> Stream a
*

*> a >: as = SCons a as
*

*>
*

*> we not only do justice to progamming by just specifying an abstract
*

*> implementation
*

*>
*

*> import Stream
*

*>
*

*> fib :: Stream a
*

*> fib | sHead x =:<= 1
*

*> & sHead (sTail x) =:<= 1
*

*> & sTail (sTail x) =:<= sZipWith (+) x (sTail x) = x where x f=
*

ree

*>
*

*> but also do we get back our familiar mode of programming with pattern
*

*> matching and constructor calls.
*

*>
*

*> sHead :: Stream a -> a
*

*> sHead (a>:_) = a
*

*>
*

*> sTail :: Stream a -> Stream a
*

*> sTail (_>:as) = as
*

*>
*

*> sZipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
*

*> sZipWith f (a>:as) (b>:bs) = f a b >: sZipWith f as bs
*

*>
*

*> -- just a utility for use on the console
*

*> sTake :: Int -> Stream a -> [a]
*

*> sTake n (a>:as) | n == 0 = [] | otherwise = a : sTake (n-1) as
*

*>
*

*> Have your choice!
*

*> Please note that the latter also is still independent of the concrete
*

*> implementation of Stream.
*

*> You could silently switch the imported module back to say
*

*>
*

*> type Stream a = [a]
*

*> (>:) = (:)
*

*>
*

*> and my program wouldn't (have to) recognise it.
*

*>
*

*> If you find this as interesting as I do, can you write other sequences =
*

in

*> either way? Primes? Hamming numbers?
*

*>
*

*> Your PAKCS source code distribution contains a file examples/inflists.c=
*

urry if

*> you want to cut short on the maths part of that tasks. (As I did).
*

*>
*

*> So my point is just that free variables seem to be a nice tool for hand=
*

ling

*> abstract data (what infinite data should be, as some argue) and that fu=
*

nction

*> calls on the left can be used to restore a convenient interface to it.
*

*> They can be used to visualize data our program never gets to see.
*

*>
*

*>
*

*> Have a nice weekend
*

*>
*

*> Sebastian
*

*> _______________________________________________
*

*> curry mailing list
*

*> curry_at_lists.RWTH-Aachen.DE
*

*> http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry
*

*>
*

_______________________________________________

curry mailing list

curry_at_lists.RWTH-Aachen.DE

http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry

Received on Mo Dez 07 2015 - 16:49:41 CET

Date: Mon, 07 Dec 2015 16:48:12 +0100

Hi,

just a short comment. I think the reason why your example works

is not due to the features of Curry but due to the unintended use

of some features. The non-strict unification operator (=:<=)

is intended to implement functional patterns, i.e., a rule like

last (_++[x]) = x

is transformed into

last xs | _++[x] =:<= xs =x where x free

in order to implement the intended semantics of functional patterns.

As an invariant, the second argument is always a variable denoting

some actual argument. Without this invariant, as in your fib example,

I don't see some declarative meaning of this operator (at least,

it has not be explored).

Best regards,

Michael

On 12/04/2015 09:04 AM, Sebastian Hanowski wrote:

ree

in

urry if

ling

nction

_______________________________________________

curry mailing list

curry_at_lists.RWTH-Aachen.DE

http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry

- application/pgp-signature attachment: OpenPGP digital signature

*
This archive was generated by hypermail 2.3.0
: Fr Sep 30 2022 - 07:15:07 CEST
*