bss03

joined 2 years ago
[–] bss03 2 points 2 years ago

I'd like to think having an inviting post might help... but I'm not sure. Probably should just try a manual post first, and then if it gets used enough, start rotating and scheduling.

Thanks for the quick reply!

[–] bss03 1 points 2 years ago

Types are erased; they don't exist are runtime. So, if the user is going to provide input at runtime to determine the processed data, you don't select that data via types (or type class instances).

You probably just want to have Cassava give you a [[Text]] value (FromRecord [Text] is provided by the library, you don't have to write it), then present the header line to the user, then process the data based on what they select. Just do the simple thing.

If the CSV file is too big to fit into memory, you might use Incremental module to read just the first record as a [Text], present that to the user, and then use their input to guide the rest of the processing. But, I wouldn't mess with that until after you have the small case worked out fairly well first.

[–] bss03 7 points 2 years ago (1 children)

Is that a stormlight archive reference?

[–] bss03 2 points 2 years ago (1 children)

Parsing function can return any of the types, we don’t know what was in the bytestring. So we’d need to deal with all variations in any case, no?

Yes, the parsing function could return anything, but that's not the exclusive source of values of the GADT.

So, yes, when consuming the output of the parsing function, you have to deal with all the variations. But, when you have types that reflect some information is known about the type index, you only have to deal with the matching constructors.

This is particularly important given the copy-paste transport of code from one context to another. You might have some code that works for a MyGADT MyType and doesn't handle all the constructors. But, when you transport that code elsewhere and ask it to handle a MyGADT a, the type system will correctly warn you that you haven't handled all the cases. This is an improvement over writing something like case x of { Right y -> stuff y; Left{} -> error "Can't happen; won't happen"; }, since I'm sure works fine in the right context, but doesn't have a type that reflects what the programmer knows about x so if it is transported to a context where that information/assumption is no longer true, that's only discovered at runtime. (This isn't the best example, but it's what I have for you.)

[–] bss03 3 points 2 years ago

Expected return calculation https://en.wikipedia.org/wiki/Expected_return there are likely better "bets" you can make. On top of that, even if the expected return is good, you have to take into account the Kelly Criterion https://en.wikipedia.org/wiki/Kelly_criterion which limits how much of your bankroll you want to spend on a longshot, and if that's less than the cost of a single ticket, buying tickets is more likely to bankrupt you than for you to win.

https://quantwolf.com/doc/powerball/powerball.html

[–] bss03 2 points 2 years ago

Is there a transcript?

[–] bss03 2 points 2 years ago (3 children)

The GADT allows some constructors to be safely unhandled when the type parameter is known.

The consuming a ParsedImage, you always have to deal with both constructors. When consuming a Image px or an AnyImage, you also have to deal with both Image constructors. When consuming a Image Pixel8Bit the type system proves that it couldn't be constructed with the Image16Bit constructor, so you only have to deal with the Image8Bit constructor.

HTH

[–] bss03 3 points 2 years ago

Article didn't explain the desire to change some common operators, tho it implied it would.

I'm uninterested in trying to graft an alternative front end on to GHC and I don't think it would actually help the ecosystem much.

If we still had a language standard, I think a transpiler from a new front end to standard Haskell might be interesting. I don't think the front end is that bad tho. Yes, records are troublesome and several languages have improved on them, but they aren't often a real pain point for me until they interact with the type system, and a new front end is unlikely to fix that. (Extensible record types ala Purescript might?)

I think it is generally a good idea for an (infix) operator to have a equivalent (prefix) function, but I don't think requiring at the language level buys you much. Good names is a cultural issue and doesn't have a technological solution (as much as I want one). People that want to strongly encourage use of an operator will just pick a name that's hard to type and pronounce and easynto confuse with other names.

I do wish we had mixfix operators ala Agda. I also think more precedence levels might help, tho I've always thought having the computer build/verify a transitive closure from pairwise ordering statements would be more flexible.

Anyway, I don't think this is thought through enough, and I don't think my thoughts here are complete enough either.

[–] bss03 3 points 2 years ago

Yeah, I generally prefer pattern matching and constructor calls, but often languages don't have GADTs or existentials. Even in GHC, existentials are still a bit "wonky", though still generally nicer to use than CPS/Codensity.

[–] bss03 2 points 2 years ago* (last edited 2 years ago)

I think the spans are all syntax highlighting/coloring. Your comment seems to have a dangling ```/span at the end to me, but that might just be the KBin->Lemmy translation.

EDIT: Also, Lemmy seems to be munging this post between the preview and the submit, due to me wanting to include some text that appears to be a dangling xml/html end tag (angle brackets removed in edit for "readability") inside backticks.

[–] bss03 1 points 2 years ago

Using a stack resolver pins all the packages in that resolver to specific versions, but pandoc-cli depends on newer versions than are available in your reoslver (lts-21.7). You might try using a newer resolver (maybe a nightly?), or using "extra-deps" to add package versions to your resolver.

Alternatively, I use cabal to install things rather than stack.

Finally, if you just want to use pandoc from the command-line, you might look for pandoc packages provided by your distribution. Often Haskell programs are distributed statically linked, at least for Haskell library dependencies, and using such a binary distribution would avoid having to (re)resolve the dependencies on your local system.

HTH

[–] bss03 2 points 2 years ago* (last edited 2 years ago) (4 children)

I put this together this evening.

{-# language GADTs #-}
{-# language RankNTypes #-}

import Data.Functor.Const

-- The GADT
data AGADT a where
    I :: [Integer] -> AGADT Integer
    S :: String -> AGADT String

type Scott_GADT a = forall fr. ([Integer] -> fr Integer) -> (String -> fr String) -> fr a

f :: AGADT a -> String
f (I x) = show x
f (S x) = x

f' :: Scott_GADT a -> String
f' x = getConst $ x (Const . show) Const

-- The Existential
data AnyGADT = forall a. MkAnyGADT (AGADT a)

type Scott_Any =
  forall r.
    (forall a. (forall fr. ([Integer] -> fr Integer) -> (String -> fr String) -> fr a) -> r) ->
    r

g :: String -> AnyGADT
g "foo" = MkAnyGADT (I [42])
g "bar" = MkAnyGADT (I [69])
g x = MkAnyGADT (S x)

g' :: String -> Scott_Any
g' "foo" x = x (\i _s -> i [42])
g' "bar" x = x (\i _s -> i [69])
g' s x = x (\_i s' -> s' s)

main = interact (unlines . fmap x . lines)
 where
  x s = case g s of { MkAnyGADT x -> f x }
  y s = g' s f'

You can swap out x for y to see the behavior is the same.

You can drop the GADT pragma, GADT definition, f, existential, g, and x (but keep all the Scott versions, includeing y) to reveal code that works "simply" with RankNTypes.

Higher-rank types and parametricity is quite powerful.

BTW, this isn't new / doesn't require the bleeding edge compiler. I'm on "The Glorious Glasgow Haskell Compilation System, version 9.0.2" from the Debian repositories.

view more: ‹ prev next ›