Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://mail.haskell.org/cgi-bin/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: Type depending on value (Marcin Mrotek)
2. Re: function application (mike h)
3. Re: Haskell triangular loop (correct use of (++)) (Rein Henrichs)
4. Re: Haskell triangular loop (correct use of (++)) (Rein Henrichs)
----------------------------------------------------------------------
Message: 1
Date: Mon, 11 Apr 2016 15:59:09 +0200
From: Marcin Mrotek <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Type depending on value
Message-ID:
<cajcfpznaaswy3_dxqvunb9x3lwsdvbrwslzxaoyfrwv57fl...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Hello,
In your function, the type `n`, and thus also the value of the
argument, would have to be known at compile time. I'm not sure if you
could make it to work. However, you can use the reflection package
(https://hackage.haskell.org/package/reflection) where you can find a
`reifyNat` function (
https://hackage.haskell.org/package/reflection-2.1.2/docs/Data-Reflection.html#g:1
) that lets you create a "temporary" type that never escapes the
callback you give to it, and so it doesn't have to be known at compile
time:
reifyNat :: forall r. Integer -> (forall n. KnownNat n => Proxy n -> r) -> r
The only requirement is that type `r` doesn't depend in any way on `n`
(but the computation itself can use it, it just has to return the same
type every time).
Best regards,
Marcin Mrotek
------------------------------
Message: 2
Date: Mon, 11 Apr 2016 14:16:18 +0000 (UTC)
From: mike h <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] function application
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
Hi,
Thanks for the comprehensive and considered answers.?Maybe I'm missing
something but defining the original function to have two definitions with a
different number of args in each? causes a compiler error ie. doing
mc :: (Integral a) => a -> amc x | x < 100 = x - 10????? -- 1 arg
mc = mc . mc . (+ 11)?????? --? no args
Thanks
On Sunday, 10 April 2016, 22:29, Silent Leaf <[email protected]> wrote:
Mike: If you seek as I think you do, to write the function mc (partially) in
point-free style, you must know this style implies no arguments, or at least
not all arguments, mentioned, that is for example here:
mc x | x < 100 = x - 10
mc = mc . mc . (+ 11)
The second line will only be checked for pattern matching if the first one
fails, so it amounts to the "otherwise" guard as here there's no pattern, so
it's a bit like the pattern that always matches (mc _ = ...)
You'll remark I did write (mc =) and not (mc x =). Point free style amounts to
describing a function through a composition of other functions, in an
arguments-free way, here for example, (mc . mc . (+11)) being the composition
of mc twice, with the "partially-applied" function (+11) == (\x -> x + 11) ==
(11+). This partially applied notation works for all operators by the way.
And for the record, the whitespace operator is a pure myth. First you can
remove all whitespace, it still works. Second, try using the same
whitespace-induced universal right-associativity with (f a b): does it amount
to (f (a b))?
The reason for this right-associativity interpretation in (mc . mc (x + 11)) is
because (.) itself is right associative: right-directed greediness could we
say, in the vocabulary of regular expression. It's also the case of ($), and
that's why we use it to counter the natural left associativity of function
application:
f $ g a == f $ (g a) == ($) f (g a) == f (g a)?? -- (using the definition of
($) here)
instead of
f g a == (f g) a
without using ($).
The whitespace is just a meaningless character (I guess, a set of characters)
used to separate juxtaposed meaningful tokens of the language when we have
either (symbol,symbol) or (nonsymbol,nonsymbol), for example respectively (!! $
/= !!$) and (f g /= fg). whenever it's a nonsymbol and a symbol, whitespace is
not necessary (a+, +a).
Then there's the automatic, implicit function application between two
juxtaposed non-symbolic tokens. But the whitespace has never been an operator
of any kind, and is totally meaningless (and optional) in (mc . mc (x + 11)).
Especially too, it's clear no whitespace survives the tokenization during the
lexical phase of the (pre?) compilation, contrarily to all real operators like
(+).
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20160411/8930f8ea/attachment-0001.html>
------------------------------
Message: 3
Date: Mon, 11 Apr 2016 21:10:44 +0000
From: Rein Henrichs <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Haskell triangular loop (correct use
of (++))
Message-ID:
<CAJp6G8yP5Yd35L=5tdmphssqx0-kmth7tzqlrpguvq_2h7i...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Compilers generally don't provide memoization optimizations because there
isn't a single dominating strategy: it varies on a case-by-case basis. (For
example, memoization of some functions can take advantage of structures
with sub-linear indexing, but this can't be done generically.)
When you can implement your own memoization yourself within the language
with exactly the properties you desire (and a number of libraries have
already done so for many common strategies ([1], [2], [3], [4])), there has
been little motivation to add an implementation to GHC which is either
inferior by way of its generality or extremely complex by way of its many
special cases.
[1]: https://hackage.haskell.org/package/MemoTrie
[2]: https://hackage.haskell.org/package/memoize
[3]: http://hackage.haskell.org/package/data-memocombinators
[4]: https://hackage.haskell.org/package/representable-tries
On Sun, Apr 10, 2016 at 10:06 PM Silent Leaf <[email protected]> wrote:
> I'm sorry to hear, no implicit memoization (but then is there an explicit
> approach?). in a pure language, this seems hardly logical, considering the
> functional "to one output always the same result" and the language's
> propensity to use recursion that uses then previous values already
> calculated. Really hope for an explicit memoization! and i don't mean a
> manual one ^^ if that is even possible?
>
> Anyway, i just don't get your function f. you did get that in mine, xs was
> the value of my comprehension list, aka [.s1..n] ++ [0]
> From there, if I'm not wrong, your function creates a list of all
> truncated lists, I supposed to be used with a call for the nth element?
> True, it memorizes all needed things, and in theory only "drops" once per
> element of the list.
>
> As for incorporating it, i'm thinking, local variable? ^^ the function
> itself could be outside the comprehension list, in a let or where, or
> completely out of everything, I don't really see the problem. then it's
> just a matter of it being called onto xs inside the comprehension list,
> like that:
> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, (x,i) <- zip xs
> [1,2..], y <- yss !! i, x /= y]
> The remaining possible issue is the call to !!... dunno if that's costy or
> not.
>
> The best way to go through the list I suppose would be by recursion... oh
> wait, I'm writing as I'm thinking, and I'm thinking:
> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, x <- xs, ys <- yss,
> y <- ys, x /= y]
> after all, why not use the invisible internal recursion? What do you think?
>
> As for the number-instead-of-number-list, the crucial point i mentioned
> was to determine the maximum number of digit (biggest power of ten
> reached), and fill up the holes of the smaller numbers with zeroes, so your
> examples would be:
> [1,2,3] = 123 --maximum size of a number = 1, no need to fill up
> [12,3] = 1203 --maximum size of a number = 2 digits, thus the hole beside
> 3 gets filled with a zero, just like on good old digital watches ^^
> Do you think extraction of clusters of digits from numbers would be
> advantageous, efficiently speaking?
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20160411/0d84b4d5/attachment-0001.html>
------------------------------
Message: 4
Date: Mon, 11 Apr 2016 21:12:23 +0000
From: Rein Henrichs <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Haskell triangular loop (correct use
of (++))
Message-ID:
<cajp6g8zrvsvyftk3ukptwgelpznp2xzn05u86ucre4av+nn...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
I should also mention that many times when you think you want memoization
in Haskell, what you actually want is to restructure your computation to
take better advantage of laziness (and especially sharing).
On Mon, Apr 11, 2016 at 2:10 PM Rein Henrichs <[email protected]>
wrote:
> Compilers generally don't provide memoization optimizations because there
> isn't a single dominating strategy: it varies on a case-by-case basis. (For
> example, memoization of some functions can take advantage of structures
> with sub-linear indexing, but this can't be done generically.)
>
> When you can implement your own memoization yourself within the language
> with exactly the properties you desire (and a number of libraries have
> already done so for many common strategies ([1], [2], [3], [4])), there has
> been little motivation to add an implementation to GHC which is either
> inferior by way of its generality or extremely complex by way of its many
> special cases.
>
> [1]: https://hackage.haskell.org/package/MemoTrie
> [2]: https://hackage.haskell.org/package/memoize
> [3]: http://hackage.haskell.org/package/data-memocombinators
> [4]: https://hackage.haskell.org/package/representable-tries
>
> On Sun, Apr 10, 2016 at 10:06 PM Silent Leaf <[email protected]>
> wrote:
>
>> I'm sorry to hear, no implicit memoization (but then is there an explicit
>> approach?). in a pure language, this seems hardly logical, considering the
>> functional "to one output always the same result" and the language's
>> propensity to use recursion that uses then previous values already
>> calculated. Really hope for an explicit memoization! and i don't mean a
>> manual one ^^ if that is even possible?
>>
>> Anyway, i just don't get your function f. you did get that in mine, xs
>> was the value of my comprehension list, aka [.s1..n] ++ [0]
>> From there, if I'm not wrong, your function creates a list of all
>> truncated lists, I supposed to be used with a call for the nth element?
>> True, it memorizes all needed things, and in theory only "drops" once per
>> element of the list.
>>
>> As for incorporating it, i'm thinking, local variable? ^^ the function
>> itself could be outside the comprehension list, in a let or where, or
>> completely out of everything, I don't really see the problem. then it's
>> just a matter of it being called onto xs inside the comprehension list,
>> like that:
>> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, (x,i) <- zip xs
>> [1,2..], y <- yss !! i, x /= y]
>> The remaining possible issue is the call to !!... dunno if that's costy
>> or not.
>>
>> The best way to go through the list I suppose would be by recursion... oh
>> wait, I'm writing as I'm thinking, and I'm thinking:
>> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, x <- xs, ys <- yss,
>> y <- ys, x /= y]
>> after all, why not use the invisible internal recursion? What do you
>> think?
>>
>> As for the number-instead-of-number-list, the crucial point i mentioned
>> was to determine the maximum number of digit (biggest power of ten
>> reached), and fill up the holes of the smaller numbers with zeroes, so your
>> examples would be:
>> [1,2,3] = 123 --maximum size of a number = 1, no need to fill up
>> [12,3] = 1203 --maximum size of a number = 2 digits, thus the hole beside
>> 3 gets filled with a zero, just like on good old digital watches ^^
>> Do you think extraction of clusters of digits from numbers would be
>> advantageous, efficiently speaking?
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20160411/3e0c3d15/attachment.html>
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 94, Issue 8
****************************************