
On Fri, 2008-10-10 at 11:14 -0700, Daryoush Mehrtash wrote:
I don't think any clarity is added by made-up notation. I think you mean In fact I was "trying" to be correct on this.
Great!
Is it wrong to show:
[()] >> f = f
as was doing:
[()] map f = [f]
Yes. Juxtaposition is always application in Haskell, and is always left-associative, and binds more tightly than any other operator. So your left-hand side means [()] applied to two arguments, map and f. This is not legal Haskell, because [()] is not a function. You intended to apply the function map to two arguments, f and [()]. The notation for that is map f [()] so, making that change, you get map f [()] = [f] This is still wrong: map :: (a -> b) -> [a] -> [b] so if f :: (() -> b) then map f [()] :: [b] but if f :: (() -> b) then [f] :: [() -> b] Unification of these types (required for an equation between the two terms) proceeds as follows: [b] = [() -> b] so b = () -> b But the unifier doesn't have a rule to solve recursive equations on types like the above; so unification fails; your rule isn't even well-typed. The correct rule is map f [()] = [f ()] where f () :: b so [f ()] :: [b] so everything type-checks. (>>) is different from map in three ways: (1) The arguments are in a different order. It's a minor issue, but of course you have to get it right. (2) >> is an infix operator (syntactically distinct from functions: map and (>>) are functions while `map` and >> are infix operators). So you can use it in the middle of your left-hand side. (2) (>>) has some subtle differences from map. The definitions are, roughly: map f xn = xn >>= \ x -> return (f x) xn >> ys = xn >>= \ x -> ys map does something interesting with the elements of its argument list: it passes them to the function f (it also builds a list of the result, which (>>) leaves to its second argument). (>>) just ignores those elements. This difference is reflected by the types, as well: map :: (a -> b) -> [a] -> [b] The type variable `a' appears twice, so in (map f xn) you know the argument to f and the elements of xn are related (in some way). (>>) :: [a] -> [b] -> [b] The type variable `a' appears only once, so in (xn >> ys) the elements of xn are just ignored; only the list structure matters.
I want to say map function f over a single element list will yield a list of single element, the element being function f.
Haskell does distinguish between a function and the result of applying that function to an argument, so the element *isn't* actually f --- it's the result of applying f to an argument. jcc