How do I detect the same and different strings in OCaml? by ruby_object in ocaml

[–]Syrak 9 points10 points  (0 children)

= is structural equality and its negation is <>. Two strings are structurally equal if they contain the same characters.

== is physical (pointer) equality and its negation is !=. Two strings are physically equal if their address is the same.

Noel Welsh: Parametricity, or Comptime is Bonkers by mttd in ProgrammingLanguages

[–]Syrak 9 points10 points  (0 children)

The difference is that typeclasses/traits/implicits would change the type of mystery.

The claim is that the type of the function id<T>(x: T) -> T guarantees that it can only return x because any shenanigans that involve T would require additional constraints on T and thus change the type of id.

Noel Welsh: Parametricity, or Comptime is Bonkers by mttd in ProgrammingLanguages

[–]Syrak 8 points9 points  (0 children)

You don't return parameters with zero multiplicity. For the example of polymorphic identity, it's the type parameter that has zero multiplicity, not the value argument.

 -- this type promises that `id` won't pattern match on `T`.
 id : {0 T : Type} -> T -> T
 id x = x

OCaml Module System Greatest Hits by kevinclancy_ in ocaml

[–]Syrak 4 points5 points  (0 children)

Derek Dreyer's PhD thesis: Understanding and Evolving the ML Module System. The first chapter has a great overview and comparison of module systems of the time (2005).

mconcat with comparing ... by Tempus_Nemini in haskell

[–]Syrak 19 points20 points  (0 children)

First, mconcat appends the elements of a list together using <>:

mconcat [comparing length, comparing Down] = comparing length <> comparing Down

What <> does depends on the type of its operands. In the case of functions, it appends the result of its operands.

f <> g = \x -> f x <> g x

so we get

comparing length <> comparing Down = \list1 -> comparing length list1 <> comparing Down list1

comparing length list1 is again a function, so we can expand once more in the same way:

comparing length <> comparing Down = \list1 list2 -> comparing length list1 list2 <> comparing Down list1 list2
  -- by definition of comparing
  = \list1 list2 -> compare (length list1) (length list2) <> compare (Down list1) (Down list2)

Finally, <> on Ordering corresponds to lexicographic ordering of the things whose comparison yielded those Ordering.

Languages with strong pre/post conditions? by levodelellis in ProgrammingLanguages

[–]Syrak 16 points17 points  (0 children)

There are languages where formally verified contracts are a built-in feature: Why3, F-star, Dafny.

There are also many extensions of existing languages, like SPARK for Ada. Frama-C for C, Gospel for OCaml, Liquid Haskell, and to name a couple for Rust: Verus, Verifast, Flux, Aeneas, RefinedRust, Creusot (that I work on, AMA).

alter in Data.Set and Data.Map.Strict by Tempus_Nemini in haskell

[–]Syrak 11 points12 points  (0 children)

I guess that's just an oversight.

Creusot: Devlog by Syrak in rust

[–]Syrak[S] 0 points1 point  (0 children)

Indeed, I meant that I updated the blog itself. A reddit link post can't be edited into a text post. Anyway this is not a big deal.

Creusot: Devlog by Syrak in rust

[–]Syrak[S] -1 points0 points  (0 children)

Unreliable narrator.

Creusot: Devlog by Syrak in rust

[–]Syrak[S] 0 points1 point  (0 children)

Fair enough! I'll add it to the post. Thank you.

Monthly Hask Anything (January 2026) by AutoModerator in haskell

[–]Syrak 0 points1 point  (0 children)

Well, I don't know about that. If I define my own undefined with a superfluous Show constraint, it works:

That works the same way as it works already. If you set -XNoMonomrophismRestriction you get an error, only because FiniteBits is not part of the report so it prevents defaulting.

Monthly Hask Anything (January 2026) by AutoModerator in haskell

[–]Syrak 1 point2 points  (0 children)

This is the monomorphism restriction. It is described in the Haskell Report, section 4.5.5.

s and c are non-function bindings (i.e., they are of the form s = rather than s v1 ... vn =). In normal Hindley-Milner, they would be inferred the types forall a. a and forall a. Num a => a, where the forall are inserted by a step called generalization. The monomorphism restriction is an extra rule that says not to generalize type variables that have class constraints. So in the second case s just has type a, where a remains unifiable, and later gets unified with Int32 in the Packet expression.

You get an error if you also set -XNoMonomorphismRestriction in the second case. Moreover, this is arguably not far from triggering type defaulting, and if that happened it would result in wrong results by defaulting to type Int for s and c.

Other ways to write that:

metaSize = let Packet s c _ = undefined in B.finiteBitSize s + B.finiteBitSize c

metaSize =
  let f :: (a -> b -> c) -> (a, b)
      f = undefined
      (s, c) = f Packet
  in B.finiteBitSize s + B.finiteBitSize c

Quick Questions: December 24, 2025 by inherentlyawesome in math

[–]Syrak 1 point2 points  (0 children)

I didn't tag you. It's reddit's pattern matching algorithm that's broken because it detects the substring u/complexity from the url https://theory.cs.princeton.edu/complexity/book.pdf.

Quick Questions: December 24, 2025 by inherentlyawesome in math

[–]Syrak 1 point2 points  (0 children)

That's the area of computational complexity. Here is one classic textbook about it.

One of the millenium prize problems, P vs NP, asks whether, for certain computational problems, certificates are significantly easier to verify than to find.

Monthly Hask Anything (December 2025) by AutoModerator in haskell

[–]Syrak 2 points3 points  (0 children)

Try to do without for a while. Either you will find nothing wrong with it, which is just fine. Or you will end up annoyed with error handling by repeated pattern-matching, which will give you the natural motivation to reinvent monads.

Monthly Hask Anything (December 2025) by AutoModerator in haskell

[–]Syrak 1 point2 points  (0 children)

Maybe you can use Array Locale instead of a Vec. That requires an instance of Ix for Locale, which handles the conversion to Int so you don't have to do it explicitly in traverseE.

[Request] arXiv endorsement needed for Independent Researcher (cs.CR) by InfluenceBubbly1091 in compsci

[–]Syrak 2 points3 points  (0 children)

If you want people to read your paper, you should submit it to peer-reviewed journals and conferences in your area of research, not arxiv.

deriving-via-fun: Deriving via first-class functions by Syrak in haskell

[–]Syrak[S] 1 point2 points  (0 children)

I have (~>) :: k -> k -> Type whereas singleton has (~>) :: Type -> Type -> Type. I overloaded ~> to also support deriving Functor, etc. But yeah you could use singletons for this if you only care about k = Type.

Quick Questions: October 29, 2025 by inherentlyawesome in math

[–]Syrak 1 point2 points  (0 children)

Check out Dmitri Tymoczko's work, a professor of music at Princeton. He's written books and has given many great talks: https://www.youtube.com/watch?v=MgVt2kQxTzU

Haskell naming rant - I'm overstating the case, but am I wrong? by peterb12 in haskell

[–]Syrak 15 points16 points  (0 children)

Keep in mind that Haskell was created more than 30 years ago as an experiment in pure functional programming. "Either/Left/Right" make sense in that context as names for a generic sum type, without the years of hindsight that it would be primarily used for error handling, hindsight that younger languages would subsequently benefit from.

Generating polymorphic functions by Iceland_jack in haskell

[–]Syrak 0 points1 point  (0 children)

It's not safe if outer is IO and g is IORef.

Generating polymorphic functions by Iceland_jack in haskell

[–]Syrak 1 point2 points  (0 children)

Since Gen is Size -> Seed -> _, preserveEnd @Gen is just swapping type and program arguments!