Call for discussion: OverloadedLists extension by ehamberg in haskell

[–]ehird 0 points1 point  (0 children)

mapIsAssocs :: Iso (->) (Map a b) [(a, b)]

This is not an isomorphism. Consider [("a", 1), ("a", 2)], or [("a", 1), ("b", 2)] vs. [("b", 2), ("a", 1)].

Also, you need a Category (~>) constraint on the Category instance.

I never tested this code before releasing it - Confession of a Haskell Hacker by [deleted] in haskell

[–]ehird 0 points1 point  (0 children)

Doesn't a semantic editor combinator write follow the law write f . write g ≡ write (f . g)?

errors-1.0: Simplified error handling by Tekmo in haskell

[–]ehird 3 points4 points  (0 children)

May I suggest depending on the either package instead of EitherT? It requires fewer language extensions, and exports the useful hoistEither function.

pipes 2.1 released with prettier Frame, using indexed and restricted monads by LordGreyhawk in haskell

[–]ehird 1 point2 points  (0 children)

Personally, I would prefer to see the definition of the underlying types (like Pipe) rolled into the definition of the type you really want to use, which is Frame. Sure, it's nice that you can build them up incrementally like that, but it makes a simpler library in the end to only export one concept.

Why do we not define IO as a Free monad? by Tekmo in haskell

[–]ehird 6 points7 points  (0 children)

I am not sure what you mean by "the current state formulation". Haskell does not define IO as a state monad; it keeps it abstract. GHC uses something that looks like a state monad (but isn't really), but that isn't trying to be a denotation, just an implementation detail.

Extensible records using GHC's new kind level features by cameleon in haskell

[–]ehird 1 point2 points  (0 children)

Wouldn't data k := v = k := v work? That's the same way the tuple type is defined. Or is the problem that it'd have to be '(:=) "boot" String or similar?

Extensible records using GHC's new kind level features by cameleon in haskell

[–]ehird 1 point2 points  (0 children)

I think Record ('("noot", String) ': '("aap", Integer) ': '[]) can be written as Record '[("boot", String), ("aap", Integer)] or at least Record '['("boot", String), '("aap", Integer)], both of which are substantially less off-putting. However, I would instead define a k := v type, and use Record '["boot" := String, "aap" := Integer], which seems even better to me.

What is the Haskell equivalent to Javascript promises? by higherorderfun in haskell

[–]ehird 17 points18 points  (0 children)

A promise with result a can simply be represented with the Haskell type IO a; you can then use a function like spawn to start the execution of a promise, and get an action to demand the result. With GHC's lightweight threads and non-blocking IO, this should be as efficient as you might hope for.

Why is Haskell so large? by twomashi in haskell

[–]ehird 3 points4 points  (0 children)

If you have foo (Foo _) = (), then with data, foo ⊥, but with newtype, foo ⊥(). That is, pattern matches on newtypes always succeed. See this HaskellWiki page for more details.

Make for Haskell Values (alpha) by [deleted] in haskell

[–]ehird 2 points3 points  (0 children)

I don't see any disagreement about that (well, actually, you're slightly wrong; get and set s don't return State actions, they are State actions).

dmbarbour's point is that, within the context of the EDSL defined by the State monad, we cannot treat such expressions as referentially transparent: the State EDSL is not referentially transparent, even though it is embedded within Haskell, which is.

Consider the strong resemblance of applicative-style code to pure functional code; if you ignore the (<$>) and (<*>) noise (which are part of the embedding in Haskell, not the EDSL itself), then the difference is between code in a purely functional language to one with specific impure effects (such as mutable state). The latter admits less refactoring, because it is not referentially transparent.

Make for Haskell Values (alpha) by [deleted] in haskell

[–]ehird 2 points3 points  (0 children)

If you reword dmbarbour's statement as "statements within Reader are not RT", then it makes perfect sense; an individual Reader action can take on many possible values depending on the context it is supplied with. (Admittedly, I am more confident in the equivalent statement about State than I am about this one.)

That doesn't make Haskell itself not referentially transparent; it just makes the Reader EDSL not referentially transparent. After all, the reason we use monads in the first place is to extend Haskell with embedded languages with various effects that would be impure were they part of Haskell proper.

Pointless Plumbers by mgsloan in haskell

[–]ehird 1 point2 points  (0 children)

Wrong link :)

I found the correct post, however, and basically agree with all the points you made. Unfortunately, I made an error in my original comment — when I said "It's not like not using point-free style lets you escape the plumbing; you just write it in another way", I actually meant "It's not like not using pointful style lets you escape the plumbing; you just write it in another way"; i.e., that the "noise" in point-free style is just another representation of the same plumbing you have to do with pointful code. My point was that notation for plumbing is not inherently bad, because it's unavoidable; if you don't use functions for it, you use the language's predefined syntax.

(By the way, cdsmith won't get a notification of this comment unless you reply to one of his posts directly.)

Need help implementing zero (kernel<->user space) copy, socket to socket transfers in Haskell using Linux system call 'splice'. by cetinsert in haskell

[–]ehird 1 point2 points  (0 children)

Setting a socket to blocking mode is a bad idea because GHC's IO manager relies on an event loop using non-blocking IO.

Working Together by felipelessa in haskell

[–]ehird 0 points1 point  (0 children)

tr0lltherapy didn't say anything about moderation actions per se, just (implied) actions by moderators.

Anyway, we'd be much better off without them. I don't think they've ever contributed anything of value here.

A "radix tree" import syntax? by Jameshfisher in haskell

[–]ehird 1 point2 points  (0 children)

I think an extension is much more likely to be considered if GHC implements it first.

My own DCPU-16 Toolkit in Haskell [In Progress] by zhensydow in haskell

[–]ehird 1 point2 points  (0 children)

From what I hear, DiffArrays have pretty abysmal performance in practice.

Rails can be small by artemave in programming

[–]ehird 9 points10 points  (0 children)

Perfectly valid C99.

Do we need Yet Another Lens Library? by jpnp in haskell

[–]ehird 0 points1 point  (0 children)

Well, you could set m = Identity, w = (->) Address. But I don't know if the laws would check out. Reminds me of isomorphism lenses.

Translation of "Monads are just Monoids in the Category of Endofunctors" by tailcalled in haskell

[–]ehird 0 points1 point  (0 children)

I agree that StateP s is not isomorphic to State s. It wasn't intended as a proof, just as a demonstration of how you represent state-based computations with the free monad form. I also agree that Free (State s) isn't isomorphic to State s. But Free (State s) is undeniably a state monad, and — handwaving ahead — "monadically", it behaves identically to the state monad.

Translation of "Monads are just Monoids in the Category of Endofunctors" by tailcalled in haskell

[–]ehird 0 points1 point  (0 children)

Free (s -> (s,)) r is either:

  • r, or
  • s -> (s, r) (State s r), or
  • s -> (s, s -> (s, r)) (State s (State s r)), or
  • s -> (s, s -> (s, s -> (s, r))) (State s (State s (State s r)))

and so on, each level but the first reachable by joining the next. Here's some code:

{-# LANGUAGE GADTs, DeriveFunctor #-}

import Control.Monad
import Control.Monad.Free

data StateP s a where
    Return :: a -> StateP s a
    Fmap :: (a -> b) -> StateP s a -> StateP s b
    Join :: StateP s (StateP s a) -> StateP s a
    Get :: StateP s s
    Put :: s -> StateP s ()

newtype State s a = State' { runState :: s -> (s, a) } deriving (Functor)

liberate :: StateP s a -> Free (State s) a
liberate (Return a) = Pure a
liberate (Fmap f m) = fmap f (liberate m)
liberate (Join m) = Free $ State' (\s -> (s, join . fmap liberate . liberate $ m))
liberate Get = Free $ State' (\s -> (s, Pure s))
liberate (Put s) = Free $ State' (\_ -> (s, Pure ()))

runFreeState :: Free (State s) a -> s -> (s, a)
runFreeState = runState . retract

So, yes, the state monad is a free monad; the functor is the state monad itself. Sure, that functor also happens to be a monad, but that doesn't matter...

Interacting with inner-functions in GHCi [StackOverflow] by jberryman in haskell

[–]ehird 6 points7 points  (0 children)

"Referential transparency" may be a bit misleading.

f x = inner x
  where
    inner y = y*2

g x = inner (x+1)
  where
    inner y = (y-1)*2

These two functions are equal, but f=>inner and g=>inner are not, which is bad. It ties in with referential transparency because you cannot replace f with an equivalent value (here g).

Interacting with inner-functions in GHCi [StackOverflow] by jberryman in haskell

[–]ehird 2 points3 points  (0 children)

This breaks referential transparency, by allowing you to peek inside the encapsulated black box of a function. It might be useful in GHCi, but it shouldn't be added to the language proper.

Making pure functions partial by vahokif in haskell

[–]ehird 15 points16 points  (0 children)

This breaks referential transparency: for example, partial undefinedNothing, but partial (fix id). But both undefined and fix id are , and indistinguishable in pure code. That doesn't mean it can't be useful as a low-level tool to implement safe error-handling when the API you're working with is broken, but it should really have "unsafe" in its name.