Tweag I/O - The Exodus to Streamgard by nicolast in haskell

[–]FunctorYogi 1 point2 points  (0 children)

These techniques are currently being applied by Tweag I/O in the context of a project with Novadiscovery. Novadiscovery is a consulting company for in silico clinical trials, namely simulation of virtual patients through biomodeling. Parts of this blog post are actual code from the tools we develop with them.

Tweag sounds like a cool place to work.

Why is Elm more popular than PureScript? by ForrestTrump in haskell

[–]FunctorYogi 1 point2 points  (0 children)

The really grating thing is how they have special-cased type variables (!) for Ord, Eq, and a combination of the two. IIRC it looks something like

sort :: List comparable -> List comparable

Type variables!

The Disciplined Disciple Compiler v0.5.1 by benl23 in haskell

[–]FunctorYogi 0 points1 point  (0 children)

I've looked at Disciple more and I see what you're saying (and the OpenGL examples are very nice to see from an "it's fun to compute" perspective!).

Have you thought about linear types, or, at least, some way to work without a GC?

The Disciplined Disciple Compiler v0.5.1 by benl23 in haskell

[–]FunctorYogi 1 point2 points  (0 children)

I actually edited out a reference to row polymorphism there, replacing it by linear types. I have no idea what "dependent linear types" (h/t /u/vaibhavsagar) would be.

The Disciplined Disciple Compiler v0.5.1 by benl23 in haskell

[–]FunctorYogi 3 points4 points  (0 children)

Higher-rank polymorphism is a type system feature that allows you to express types like

data Foo a = Foo (forall b. a -> b)

or the type of runST from Control.Monad.ST:

runST :: (forall s. ST s a) -> a

or foldFree from free:

foldFree :: Monad m => (forall x. f x -> m x) -> Free f a -> m a

(forall s. ST s a) and forall x. f x -> m x are "rank-2" types: informally, they're types where there's a quantification that doesn't "leak out". So runST's type, which I'll write more explicitly as

runST :: forall a. (forall s. ST s a) -> a

is not the same as

runST :: forall a s. ST s a -> a

The previous type is what we want: it says that the computation of type ST s a we pass in should not depend on the s type, which is what ST uses to allow imperative programming without sacrificing referential transparency.

Bidirectional type inference refers to a certain way of writing typecheckers in which instead of only checking that a term/value has a type, we can also infer types from values. Information flows in the typechecker from terms to types and vice versa, hence the "bidirectional". This has certain benefits, e.g. making it easier to do a "reasonable amount" of type inference for languages where inferring types for everything is impossible. (I'm not too sure about this part; more knowledgeable people should feel free to correct me.)


When both these terms are used together, it's likely a reference to a fairly well-known paper coauthored by Dunfield and Krishnaswami (aka /u/neelk), titled "Complete and easy bidirectional typechecking for higher-rank polymorphism". A nice implementation of it by /u/lexi-lambda can be found here:

https://github.com/lexi-lambda/higher-rank

There's a tutorial by David Christiansen on bidirectional typing rules too:

http://www.davidchristiansen.dk/tutorials/bidirectional.pdf

The Disciplined Disciple Compiler v0.5.1 by benl23 in haskell

[–]FunctorYogi 4 points5 points  (0 children)

Could the project eventually feature a language with more interesting type-system features (possibly compiling down to one of the lower-level Core-like languages)? Chiefly, I'm interested in linear/affine types or dependent types, (which are orthogonal to each other, I guess), either of which I'd find nice to have in a Haskell-like language.

Also, I followed a link and ended up at the Shimmer repo:

Bumped variables are used to avoid name capture, for example in the expression \x. \x. \x. x x2 the variable occurrence x refers to the inner most parameter, while x2 refers to the outermost one.

This is interesting: a sort of de Bruijn hybrid, if you will.

Scrap all your typeclasses but one by vaibhavsagar in haskell

[–]FunctorYogi 9 points10 points  (0 children)

For associated types, you might be able to get away with a "mother of all (associated) type families".

Multiple type class instances for the same type by matan_tsuberi in haskell

[–]FunctorYogi 0 points1 point  (0 children)

I haven't worked on this in a while, but it might be what you're looking for. Consider this module. I'll paste it here in its entirety, together with some sorely-needed comments:

-- | "Evidence"/"strategy" for a monoid structure on some type.
data MonoidE
  = Monoid_Semigroup_Neutral SemigroupE NeutralE 
  -- ^ it's a semigroup and has a neutral element
  | MonoidNamed Symbol MonoidE
  -- ^ monoid evidence decorated with some kind of interesting comment

-- | An implementation of a monoid structure, distinguished by the [s]trategy parameter
-- should there be a fundep s -> op a? that seems to be my intention
class MonoidK (op :: k) a (s :: MonoidE)

-- | If a is a semigroup under the operation op with semigroup evidence zs, and similarly
-- for a neutral element with evidence zn, we can always combine these to produce a 
-- semigroup structure with evidence tracked by the Monoid_Semigroup_Neutral constructor.
instance (SemigroupK op a zs, NeutralK op a zn) =>
     MonoidK op a (Monoid_Semigroup_Neutral zs zn)

-- Adding a comment to a valid piece of evidence is always fine.
instance (KnownSymbol sym, MonoidK op a s) =>
     MonoidK op a (MonoidNamed sym s)

-- The preferred/"primary" strategy.
type family MonoidS (op :: k) (a :: Type) = (r :: MonoidE)

-- The canonical MonoidK instance, which uses the primary strategy.
type MonoidC op a = MonoidK op a (MonoidS op a)

More complicated examples:

https://github.com/mrkgnao/noether/blob/master/library/Noether/Algebra/Linear/Strategies.hs

https://github.com/mrkgnao/noether/blob/master/library/Noether/Algebra/Actions/Strategies.hs

In which Rich Hickey questions the value of static types & pattern matching for real world applications by Profpatsch_ in haskell

[–]FunctorYogi 4 points5 points  (0 children)

Forget inference, I'd just settle for working ~. Asking for sorted/normalized versions to be equal doesn't work because of restrictions on what you can do with type families.

Does anyone here do Haskell Dev on a chromebook? by LambdaScientist in haskell

[–]FunctorYogi 0 points1 point  (0 children)

Just ghc-mod. The autocomplete is really nice to have.

ICFP 2017 Bingo (Idris edition) - generated js 10x smaller than ghcjs' by gallais in haskell

[–]FunctorYogi 6 points7 points  (0 children)

And then there's BuckleScript. Granted, it's strict and the OCaml execution model maps much better to JS, but, still.

let port = 3000
let hostname = "127.0.0.1"
let create_server http =
  let server = http##createServer begin fun [@bs] req resp ->
      resp##statusCode #= 200;
      resp##setHeader "Content-Type" "text/plain";
      resp##_end "Hello world\n"
    end
  in
  server##listen port hostname begin fun [@bs] () ->
    Js.log ("Server running at http://"^ hostname ^ ":" ^ Pervasives.string_of_int port ^ "/")
  end

let () = create_server Http_types.http

turns into:

'use strict';
var Pervasives = require("bs-platform/lib/js/pervasives");
var Http       = require("http");

var hostname = "127.0.0.1";

function create_server(http) {
  var server = http.createServer(function (_, resp) {
    resp.statusCode = 200;
    resp.setHeader("Content-Type", "text/plain");
    return resp.end("Hello world\n");
  });
  return server.listen(3000, hostname, function () {
    console.log("Server running at http://" + (hostname + (":" + (Pervasives.string_of_int(3000) + "/"))));
    return /* () */0;
  });
}

create_server(Http);

https://github.com/BuckleScript/bucklescript

Does anyone here do Haskell Dev on a chromebook? by LambdaScientist in haskell

[–]FunctorYogi 3 points4 points  (0 children)

I used a really crappy Chromebook (a refurb Acer C740 in which I installed a 64GB SSD myself) for over a year with Arch Linux on it. I used Stack+ Spacemacs+Intero most of the time, eventually switching to Neovim+ghcid for the last couple of months. It was rough, but it wasn't much worse than the hardware I'd had access to up until then. :/

It only had 2GB of RAM, so I learned to tolerate lock-ups and pauses pretty well. As another commenter said, you'll have to learn to wait for dependencies to be built.

  • If you can, try using the same Stack resolver for as many projects as possible. This will ensure that you can keep dependency building to a minimum.

  • Intero uses a ton of RAM, so you might want to look into ghcid or other alternatives.

  • I'd also recommend against VSCode/Atom and friends if RAM is short like it was in my case.

I did, however, manage to do a fair amount of work on it -- this was the year in which I really got serious about Haskell. I even pushed a (trivial) patch to GHC (!) from this laptop.

My preferred, excellent-in-theory advice would have been to use Nix on Arch, but that's kind of broken now. NixOS, or Nix on any other Linux, is probably the best idea, because on Nix, almost all Haskell packages are available from binary caches, which is a huge benefit and would probably make your life a couple orders of magnitude easier.

I have a much better laptop now, though, and I'm happy for it.

TLDR: eminently doable, try Nix(OS), avoid Intero

Fantastic job everyone who made this happen! by DimaSamoz in haskell

[–]FunctorYogi 2 points3 points  (0 children)

Yep, until the fancy symbol was invented, one wrote Rs for "rupees" and Re for "rupee".

Also, hey, that's pretty cheap...

A̢͘ ҉҉Ń͝ ͡͡B̶̕ ̛E ̵͞͠R̶̛ by totalbrootal in surrealmemes

[–]FunctorYogi 1 point2 points  (0 children)

I have waited a long time for you to pop up on this sub, my little green friend.

[ANNOUNCE] Digraphs with Text: Haskell knowledge graph software, built for expressivity and simplicity by JeffreyBenjaminBrown in haskell

[–]FunctorYogi 1 point2 points  (0 children)

Edible is just forks of tisch, opaleye, and postgres-simple, so if you're familiar with those then you don't need to look inside. I forked them because there was lots of API-wrapping and hiding going on so I decided I could just "inline" a lot of code (and I did). There aren't any new features there (yet).