posted by tomkirbygreen

]]>C

posted by Charles

]]>

posted by Novox

]]>posted by paks8150

]]>It would be great if this expression type-checked in C#: s.Select(1+).

Then about \x -> x **vs** x |-> x. I must admit the mathematical notation is less noiseful.

In both situations an IDE **should** automatically transform both symbols into their unicode equivalents.

So even if typing ==, it will be transformed (graphically) to =, possibly colored differently, and remain unambiguous.

It's also funny, because when trying to model boolean expressions in Java back in 2002, it became very obvious to use this approach outlined by Erik. Still, not entirely convinced it's superior to the functional approach but indeed it does provide some abstraction over structure: F# has these Active Patterns which may be a solution to that problem, haven't looked into it. Let me try again, forgot the old implementation...

It's definitely it's something interesting to ponder.

n+k patterns. Not enough data to conclude non-/justification, must search...

public abstract class Bool { public abstract Bool Not(); public abstract Bool And(Bool _); public abstract Bool Or(Bool _); } public class False : Bool { private False() { } public static readonly Bool A = new False(); public override Bool Not() { return True.A; } public override Bool And(Bool _) { return this; } public override Bool Or(Bool that) { return that; } } public class True : Bool { private True() {} public static readonly Bool A = new True(); public override Bool Not() { return False.A; } public override Bool And(Bool that) { return that; } public override Bool Or(Bool _) { return this; } } public static class Bools { public static Bool Box(this bool x) { return x ? True.A : False.A; } public static bool Unbox(this Bool x) { return x is True; // unsafe : x == True.A; unless we seal } public static Bool Andy(this Bool a, Bool b) { return (a.Unbox() && b.Unbox()).Box(); } public static Bool Ory(this Bool a, Bool b) { return (a.Unbox() || b.Unbox()).Box(); } }

Day.Exit;

posted by exoteric

]]>posted by ShinNoNoir

]]>Fantastic job. Thanks so much and I am really looking forward to watching all the remaining chapters!

Radu

posted by rgruian

]]>

...It's a fun idea to use a Lisp-based editor to "type" Haskell

posted by exoteric

]]>

abs1 n = n, n >=0

I got error and could not coninue the next branch. I guess I have to edit my script and load it. How?

posted by chudq

]]>posted by chudq

]]>```
```abs n | n >= 0 = n

| otherwise = -n

posted by exoteric

]]>`f x = 4711`

posted by chudq

]]>posted by exoteric

]]>

Do yourself a favour and type your code in a .hs file, use ":r" to reload it each time and just use the interactive prompt to test the functions, it'll save you some head aches!

posted by sylvan

]]>

Keep up the great work!

posted by Denzil Long

]]>

In the function

add = \x -> (\y -> x+y)

how can the inner function \y access the value of x when it is defined to take only a single parameter y?

And why does the expression

(-1) 3

return an error, but

(/2) 6

is fine?

-Roy

posted by rfeague

]]>

Second (or first as it were) problem. See this code in C#

Func<int, Func<int, int>> add = a => b => a + b; int add_1_2 = add(1)(2); Console.WriteLine(add_1_2);

This is the same pattern as in Haskell and all the outer values are captured and accessible to the inner expressions. Erik can elaborate on this more than me.

A more philosophical question, is this

abs n | n >= 0 = n | otherwise = -n

really better than this

abs n | n ≥ 0 = n | n < 0 = -n

posted by exoteric

]]>add = \x -> (\y -> x+y)

If we apply the function to e.g. 3, we'll get:

add 3 = {- replace add by its definition -} (\x -> (\y -> x+y)) 3 = {- now substitiute 3 for x, i.e. function application -} {- no further substitution possible -}

Now, if we'll apply this result to e.g. 4, we'll get:

(\y -> 3+y) 4 = {- function application, sub 4 for y -} 3+4 = {- use the definition of (+) -} 7

posted by ShinNoNoir

]]>

The only solution I can come up with is to bind it to a name (prefix though) and then use that name in a secion (infix), something like: let subtract = (-) in (`subtract` 1) 3

There must be a better way...

posted by MonkeyGuru

]]>

The Haskell prelude defines flip as:

-- flip f takes its (first) two arguments in the reverse order of f.flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x

using flip we can write (-1) 3 as:

(flip (-) 1) 3

Also, the prelude has a substract function defined as:

subtract :: (Num a) => a -> a -> a subtract = flip (-)

posted by paks8150

]]>

Please also check this out:

FP Course using Haskell: In English (class notes or 'transparencies' in PDF format are on this page and are also helpful):

http://verify.rwth-aachen.de/fp05/

Course and Exercise Sessions Videos:

http://video.s-inf.de/#FP.2005-SS-Giesl.%28COt%29.HD_Videoaufzeichnung

All videos starting with V are videos. Videos Starting with U are exercise session. Full resolution videos are about 800mb and lowres are about half that (400mb or so?)

the reddit thread is here.

http://www.reddit.com/r/programming/comments/9xo3m/lectures_on_functional_programming_using_haskell/

posted by reddit

]]>posted by exoteric

]]>This is analogous to correlated subqueries in SQL, which also tax my brain.

I guess what I find weird about \x -> (\y -> x+y) is:

1. the syntax suggests to me that the definition of \y is complete within the parentheses, but it has a dependency that reaches outside the parens and raises questions about the limits of scope; and (related)

2. in other programming contexts one learns to read parentheses from innermost to outermost. But here we need to read it left to right.

I guess it's just going to take a while to learn to think like the Haskell parser.

Another example that twists my C/C++ programmer's brain: we can define tail as

mytail (_:xs) = xs

Very logical, but this assumes that the language is able to deconstruct the list input to understand that it can be thought of as a single element added to a list. Cool that the language can do that, but not obvious, and leaves me wondering what other sorts of deconstructions it is capable of making that are not obvious. Can I do drop2 (b:(a:xs)) = b:xs to drop the second item? How will we know the limits of such constructs without just trial and error? I'm sure this will become more clear as we go on.

re: (-1) 3 --- agreed that the problem is that -1 can be read (and apparently IS read) as negative 1. Surprising then that we can't use ((-)1) 3 or something analogous. The flip business seems very convoluted. But I suppose this is a minor syntactic quirk originating from the overloaded use of the - symbol, and since it only impacts a syntax shortcut, it's probably not worth worrying too much about.

posted by rfeague

]]>foo x y = x * (y+x)

About the language being able to deconstruct lists, that's because Haskell is designed to deconstruct
** any** algebraic data type (ADT).

-- ADT for a linked list: data List a -- [a] <--> List a = Cons a (List a) -- (:) <--> Cons | Nil -- [] <--> Nil -- ADT for a binary tree: data BTree a = Node (BTree a) (BTree a) | Empty

And yes, your drop2 function does exactly what you say it does, although you don't need the inner parentheses in the pattern.

About the minus business, yes, that's a syntax quirk.

posted by ShinNoNoir

]]>let abs x = if x < 0 then -x else x

but it won't let you enter the type information. WinHugs doesn't allow this at all.

posted by KenBu

]]>

1. safetail

safetaila :: [a] -[a] safetaila xs = if null xs then [] else tail xs safetailb :: [a] -[a] safetailb xs | null xs = [] | otherwise = tail xs safetailc :: [a] -[a] safetailc [] = [] safetailc (_:xs) = xs

2. Implement (||) in three different ways

(||!) :: Bool -Bool -Bool True ||! True = True True ||! False = True False ||! True = True False ||! False = False (||@) :: Bool -Bool -Bool False ||@ False = False _ ||@ _ = True (||#) :: Bool -Bool -Bool False ||# b = b True ||# _ = True

3. Redefine (&&)

(&&$) a b = if a == True && b == True then True else False

4. Redefine (&&) again

(&&%) a b = if a == True then b else False

posted by paks8150

]]>posted by lambdaf

]]>

*Excellent* series, btw. Can't thank you all enough for doing this (and I must say I'm enjoying the commentary from the clearly knowledgable community members such as exoteric and ShinNoNoir nearly as much...). Cheers!

posted by Brian Hartung

]]>posted by PCB

]]>C

posted by Charles

]]>

my shot at the homework. Incomplete, of course.

--Case of dynamic dispatch...

class Bool {

public:

virtual Bool* operator!(void) = 0;

virtual Bool* operator&&(Bool&) = 0;

virtual Bool* operator||(Bool&) = 0;

};

class True : public Bool {

Bool* operator!(void);

Bool* operator&&(Bool& ref) {

return &ref;

}

Bool* operator||(Bool& _) {

return new True();

}

};

class False : public Bool {

Bool* operator!(void);

Bool* operator&&(Bool& _) {

return new False();

}

Bool* operator||(Bool& ref) {

return &ref;

}

};

Bool* True::operator!(void) {

return new False();

}

Bool* False::operator!(void) {

return new True();

}

int main(void) {

class Bool *Bt = new True();

class Bool *Bf = new False();

*Bt&&*Bf;

*Bf&&*Bt;

*Bf||*Bt;

!*Bf;

return 0;

}

--Case of double dispatch...

#include <iostream>

using namespace::std;

class Bool {

public:

virtual Bool* AND(Bool&) = 0;

// TF is for true or false

virtual Bool* TF(void) = 0;

};

class True : public Bool {

Bool* TF(void) {

cout<<"True"<<endl;

return new True();

}

Bool* AND(Bool& ref) {

return ref.TF();

}

};

class False : public Bool {

Bool* TF(void) {

cout<<"False"<<endl;

return new False();

}

Bool* AND(Bool&) {

return TF();

}

};

int main(void) {

Bool *Bt = new True();

Bool *Bf = new False();

Bt->AND(*Bf);

Bf->AND(*Bt);

Bt->AND(*Bt);

return 0;

}

Sohail Qayum Malik

posted by Aeon

]]>