# The similarity between Haskell and Prolog

**URL:** <https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160>\
**Category:** General\
**Created:** [January 10, 2024, 3:20pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160 "2024-01-10T15:20:21Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [January 24, 2024, 7:40am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/33 "2024-01-24T07:40:53Z")

</div>

I’m about 10 problems into AoC2022 in Haskell at the moment. It made me realise just how much of the Prolog I’ve written is basically functional programming. In terms of my style I’d say maybe 90%. I do wonder however – when Prologness is maximised – what that percentage could be in the best case scenario.

I suppose “Prologness” is maximised when the code can maximally lean on implicit backtracking or where the homoiconicity of the language is a significantly utilised.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [January 24, 2024, 10:47pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/35 "2024-01-24T22:47:19Z")

</div>

I saw a talk once about the duality between logic and computation. Remember the guy mentioning how we are destined to – as a result – make every discover twice: one by a logician and the other by a computer scientist 🙂

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 3, 2024, 8:32am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/40 "2024-02-03T08:32:48Z")

</div>

Haskell is quite nice. To me, its just like Prolog from a practical perspective because most Prolog that I wrote is functional programming in spirit. Passing things around by value is really convenient. Even after a year in Prolog I’d still be writing things like X+1 as a predicate variable by accident. Piping functions together also feels very natural. I’d wish for Prolog to have similar syntactic sugar to the “.” operator such that **(f . g) x** results in **f(g(x))**. Of course its not just sugar in Haskell, its literally “all you need” _ala_ lambda calculus. I guess the motivation for a functional logic programming language are fairly obvious.

I’m on Day 17 AoC 2022. My benchmark for conciseness is @BarrensZeppelin , his solutions in Python/Prolog are [here](https://github.com/BarrensZeppelin/adventofcode2022). My Haskell ones are [here](https://github.com/emiruz/adventofcode2022/tree/main). Its meaningful to me that with a couple of weeks of Haskell and a limited vocabulary, one can produce concise solutions to fiddly problems. I think it indicates something about the expressiveness of the paradigm.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 3, 2024, 8:40am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/41 "2024-02-03T08:40:08Z")

</div>

> [@anon95304481](#):
>
> Also  
> might then be machine with other specs than that from @emiruz .

I run a 2.4GHz i7 CPU from deep deep yesteryear. _Ceteris paribus_, I’m not really surprised that compiled languages run faster than Prolog implementations if for no other reason than that Prolog is typically interpreted. My understanding is that SWI doesn’t use JIT compilation? I think if you assume even a small runtime multiple for SICStus vs SWI (and I understand that there is a big one, and SICStus compiles), it would likely beat 0.3s, _ceteris paribus_.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 3, 2024, 9:29am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/43 "2024-02-03T09:29:15Z")

</div>

BogoMIPS: 5606.40, and its 2.8Ghz not 2.4 – correction.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [February 3, 2024, 10:13am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/44 "2024-02-03T10:13:28Z")

</div>

Prolog is typically compiled to byte code executed by a virtual machine. SWI-Prolog has JIT indexing.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 12, 2024, 10:16pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/48 "2024-02-12T22:16:18Z")

</div>

Haskell has something called “sequences”. They are based on [finger trees](https://en.wikipedia.org/wiki/Finger_tree), and its a purely functional structure which allows for O(1) reads/writes to beginning and end of a sequence. Its also O(log n) for random access.

Since its purely functional, the concept probably ports to Prolog with all the same benefit: no more O(n) to access the last element 🙂

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 12, 2024, 10:31pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/49 "2024-02-12T22:31:39Z")

</div>

Haskell is slow, where Prolog is slow: frequent random access or mutation of array-like structures. These sorts of operations map poorly to the hardware’s memory model and can end up orders of magnitude slower compared to a compiled language with native arrays.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 22, 2024, 11:34am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/50 "2024-02-22T11:34:02Z")

</div>

I eventually finished AoC2022 in dribs and drabs of time. Its [here](https://github.com/emiruz/adventofcode2022/tree/main). I can’t really tell if its more/less difficult than 2023 which I had solved in Prolog.

Initially I was sure that all the planning problems were going to take me lots more LOC in Haskell but the opposite was true. DFS, BFS, Dijkstra, A\*, state space definition, and so on, were more succinct to write down compared to my 2023 experience because passing things around by value requires less boiler plate. E.g. `f . g x ` rather than `g(X,Y), f(Y)`.

I think control statements such as function guards and `case` make it easier to express conditional variation on what is otherwise the same code. In Prolog I end up explicitly writing variants of the same predicate in order to use pattern matching for the same thing, which is often much more verbose.

What I prefer in Prolog is the ability to express data in the language directly. E.g. dynamically add some predicates at the beginning of the code, and then use it throughout without having to pass it around.

I’d like to say that clpfd is some kind of an advantage but – and not for lack of trying – I still can’t understand what its for. Things I’ve solved with it in AoC2023, I now know are just as easy without it. Meanwhile, I did miss CHR. I had found it very useful for simulating how a state evolves through simple constraints.

Throughout, I found myself reasoning about problems in Prolog. What I then wrote down in Haskell is very much “Prolog inspired”: I could not find a Haskell repo with a lower average LOC than mine (\<27 LOC mean), which I attribute largely to this approach. To wit, I find that Prolog is still the superior “mindware” for me, even though its Earthly incarnations are more verbose than I’d like them to be.

@meditans, it’d be great to hear your thoughts RE Haskell/Prolog since you know both languages better than me and you seem to prefer Prolog 🙂

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [February 22, 2024, 2:49pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/51 "2024-02-22T14:49:17Z")

</div>

I won’t find the time to comment in detail on your Prolog code but I can give you useless observations. Every language gives you the ability to “not repeat yourself”. It is easier in Prolog, since you can write mini-interpreters with very low friction. If your goal is to ~~write less~~ end up with less code eventually, you would write it out once, then figure out the common parts, and almost always you will find a way to abstract the common parts to an ad-hoc interpreter. But this is of course the exact same rabbit hole that every LISPer has visited.

I tried to like Haskell and couldn’t because it is so restrictive in its extensive syntax. Prolog has almost no syntax and I feel like I am running free which is a good thing to do when you are not at work 😃

PS: it is more approachable if you have a concrete example of code that you think is repetitive in Prolog. But you can find a lot of repetitive code in the standard libraries of SWI-Prolog, too. Sometimes it is for efficiency and sometimes probably to make it easier to read. Not sure.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [February 22, 2024, 3:21pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/52 "2024-02-22T15:21:44Z")

</div>

> [@emiruz](#):
>
> I’d like to say that clpfd is some kind of an advantage but – and not for lack of trying – I still can’t understand what its for.

Referring to [SWI-Prolog -- Manual](https://eu.swi-prolog.org/pldoc/man?section=clpfd:)

> There are two major use cases of CLP(FD) constraints:
> 
> 1. **declarative integer arithmetic** ([section A.9.3](https://eu.swi-prolog.org/pldoc/man?section=clpfd-integer-arith))
> 2. solving **combinatorial problems** such as planning, scheduling and allocation tasks.

Point 1. is all about supporting true relational arithmetic in a relational programming language, so not really useful when doing a language comparison. Standard Prolog has functional arithmetic (N (ground) inputs, 1 output) so that’s just going to be equivalent to Haskell (a functional programming language), except that Haskell is much richer since you can embed your own functions/types in otherwise numeric expressions. (To be fair, some Prologs are better at this than SWIP’s current compiled arithmetic.)

Point 2. is about potentially optimizing some problems by using a test then generate strategy. If that doesn’t fit, then clpfd probably isn’t the solution.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 22, 2024, 4:08pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/53 "2024-02-22T16:08:48Z")

</div>

@ridgeworks, those are the reasons I wanted to like clpfd. [This](https://emiruz.com/post/2023-11-13-domicles/) is the probably the best thing I’ve built using it. I think that one easily assumes that clpfd is a solver, but it isn’t. Its just something you might use to build a problem specific solver, taking care not to use any impure Prolog or tabling in an incompatible way of course 🙂

I had an actual scheduling problem the other day. I smashed it out in Prolog in about 2 hours. I used the fdset\_ predicates from clpfd. It was beautiful and I was over the moon with it. Shortly after, the team started asking me to add more constraints, and more participants to the schedule.

Very quickly it became impossibly slow, because I had essentially written a brute force search…quickly. However, when I needed to make it scale a bit, I had to backtrack and start thinking carefully about the data structure, the solution space, the search algorithm. Suddenly, clpfd has nothing useful for me, and unless I was going to spend a week coding a search algorithm from scratch, it was just much easier to move the problem to MiniZinc instead where I could invoke solvers, and wouldn’t have to write my own. That’s what I think the challenge is with clpfd (for me).

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 22, 2024, 4:27pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/55 "2024-02-22T16:27:59Z")

</div>

It may be tricky to find folks who’ve solved all of AoC in both Prolog and Haskell (being two fairly exotic languages), if that’s what you’re looking for. Our resident @BarrensZeppelin does it in Python and Prolog. His AoC 2022 Prolog solutions are [here](https://github.com/BarrensZeppelin/adventofcode2022).

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [February 22, 2024, 5:11pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/56 "2024-02-22T17:11:38Z")

</div>

> [@anon95304481](#):
>
> Can clpBNR do this faster?

```prolog
?- time(([U,V]::integer(0, 1000000000), {(36641*U)-24 == 394479375*V})).
% 96,065 inferences, 0.009 CPU in 0.009 seconds (100% CPU, 10781613 Lips)
U::integer(2303938, 997701977),
V::integer(214, 92671).

```

```prolog
?- time(([U,V]::integer(0, 1000000000), {(36641*U)-24 == 394479375*V}, solve([U,V]))).
% 4,284,164 inferences, 0.439 CPU in 0.440 seconds (100% CPU, 9750102 Lips)
U = 346688814,
V = 32202 ;
% 4,427,744 inferences, 0.438 CPU in 0.439 seconds (100% CPU, 10103822 Lips)
U = 741168189,
V = 68843 ;
% 2,734,115 inferences, 0.271 CPU in 0.271 seconds (100% CPU, 10091898 Lips)
false.

```

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [February 22, 2024, 9:40pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/57 "2024-02-22T21:40:02Z")

</div>

> [@brebs](#):
>
> ```prolog
> ?- time(([U,V]::integer(0, 1000000000), {(36641*U)-24 == 394479375*V})).
> % 96,065 inferences, 0.009 CPU in 0.009 seconds (100% CPU, 10781613 Lips)
> U::integer(2303938, 997701977),
> V::integer(214, 92671).
> 
> ```

Some caution is necessary in interpreting these results. Note that the clpfd results are quite tight but take considerably longer to get there. The reason for that is that clpBNR has a throttling mechanism on the fixed point iteration, which terminates the iteration after some count (user definable) unless the intervals are being narrowed by some minimum amount (~10% IIRC). You can observe the effect:

```prolog
?- set_prolog_flag(clpBNR_iteration_limit,100000).
true.

?- time(([U,V]::integer(0, 1000000000), {(36641*U)-24 == 394479375*V})).
% 3,186,237 inferences, 0.731 CPU in 0.731 seconds (100% CPU, 4360867 Lips)
U::integer(76891234, 923103915),
V::integer(7143, 85742).

```

but it’ll take some time to achieve the same bounds as clpfd. And as clpBNR isn’t particularly optimized for integer problems, I would expect to achieve the same tight result might actually take longer than clpfd.

On the other hand:

> [@brebs](#):
>
> ```prolog
> ?- time(([U,V]::integer(0, 1000000000), {(36641*U)-24 == 394479375*V}, solve([U,V]))).
> % 4,284,164 inferences, 0.439 CPU in 0.440 seconds (100% CPU, 9750102 Lips)
> U = 346688814,
> V = 32202 ;
> % 4,427,744 inferences, 0.438 CPU in 0.439 seconds (100% CPU, 10103822 Lips)
> U = 741168189,
> V = 68843 ;
> % 2,734,115 inferences, 0.271 CPU in 0.271 seconds (100% CPU, 10091898 Lips)
> false.
> 
> ```

This demonstrates the advantage of not spending a lot of time on the fixed point iteration (due to low throttling value) and using the labelling to derive solutions, which has to be done anyway to separate the two solutions.

I’m not overly happy with this sort of “engineering” requirement but haven’t yet seen a better way of addressing the problem. (Note that Tom Hickey’s CLIP system (CLP(Intervals)) .ca 2000 proposed a similar mechanism.)

> [@anon95304481](#):
>
> Would it be possible to make clpBNR  
> standard bundle of [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual), so that don’t need install a pack?

Not really my decision to make, but I will support any reasonable alternative, or complement, to a pack. Any particular problem with packs? I’ve been working with @jan to get a version of clpBNR on SWISH. Maybe that with a pack based solution for local use is good enough?

Anyway this is drifting off-topic so maybe we need a new one if this discussion has any legs.

---

<div class="post-metadata">

**Author:** ![meditans](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/meditans/32/1768_2.png) [@meditans](https://swi-prolog.discourse.group/u/meditans)\
**Post date:** [February 23, 2024, 7:04pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/59 "2024-02-23T19:04:37Z")

</div>

> [@emiruz](#):
>
> @meditans, it’d be great to hear your thoughts RE Haskell/Prolog since you know both languages better than me and you seem to prefer Prolog 🙂

I can try jotting down my two cents on what I think is an interesting distinction (my perspective is biased by being very interested in mathematical logic).

**tl;dr** Haskell and Prolog have two different ideas of what computation _means_, in the sense of what’s the underlying mechanism of computation.

There is this beautiful result in type theory called [Curry–Howard correspondence](https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence) (The Curry here is Haskell Curry, from which the name Haskell comes from). It shows you that in a type theory (you can think in haskell, even if the correspondence is not perfect) types have a direct relations with logical statements, and a program with a given type corresponds to a proof of the corresponding logical statements.

Since you know some haskell, here’s an example:

```haskell
f :: a -> Either a b
f a = Left a

```

Now, the type `a -> Either a b` corresponds to the logical propositional formula `A → A ∨ B`, and actually the fact that you can write a program with that type at all is because that proposition is a tautology. The implementation of the function is a proof of that proposition.

In fact the program above is also the shortest program that you could write. Another program could be:

```haskell
f a = snd (42, Left a)

```

Crucially, _evaluating_ an expression in haskell means starting with a complicated proof (your code), and simplifying it until it becomes the simplest proof possible (your result). So, in this framework (type theory and haskell) computation _means_ normalization (in the sense of simplification of a program - a proof - to its maximum degree, the so called normal form).

In the world of prolog instead, computation _is_ essentially the search of a suitable deduction tree. So, not the normalization of a proof. Instead it is the search of a proof, in principle by any mean possible. Logic + control, they say, but I can imagine the control part being a very wild thing.

I think this is fundamentally a more stimulating conceptual framework for thinking about computational phenomena. But apart from the philosophical enjoyment, what is there to gain by adopting this perspective?

I think it nudges us toward thinking of programs that are not easily expressed in the other paradigm. As an example, a program that sees it’s own deduction process, notices useful patterns, and finds ways of restructuring the computation to exploit that pattern. A sort of [CDCL](https://en.wikipedia.org/wiki/Conflict-driven_clause_learning) for SAT solvers, but on steroids.

Hope it was useful @emiruz 😄

_ps._ I’m not the first to present this as the more interesting distinction. I must have read this somewhere (it could be in one of Triska’s video on youtube but I can’t trace it down).

_pps._ I’m also not sure I _prefer_ prolog to haskell. Both are beautiful, and flawed; which one to use depends on a lot of considerations. I also like lisps (clojure in particular). It is true however that for now my ideal language would be based on ideas taken from the prolog way of seeing computations.

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 24, 2024, 10:12am UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/62 "2024-02-24T10:12:00Z")

</div>

Thank you for the insightful response!

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [February 24, 2024, 4:09pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/65 "2024-02-24T16:09:03Z")

</div>

> [@anon95304481](#):
>
> The only problem I see, by invoking Curry–Howard correspondence, which originally  
> talked about [simple types](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus), that if this really were the case then Haskell would be  
> indeed normalizing.

That Haskell, like the lambda calculus, has a sort of replacement scheme for simplifying equations, doesn’t imply that it terminates. I.e. that it “normalises” doesn’t mean it succeeds in every case, and I guess that is akin to the halting problem.

Further, you can also restrict yourself in Haskell to just the decidable portion of the language – or just be mindful of the problematic cases like in Prolog – in which case the result will presumably be strongly normalising.

---

<div class="post-metadata">

**Author:** ![anon419083](https://avatars.discourse-cdn.com/v4/letter/a/53a042/32.png) [@anon419083](https://swi-prolog.discourse.group/u/anon419083)\
**Post date:** [February 24, 2024, 7:12pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/69 "2024-02-24T19:12:28Z")

</div>

> [@anon95304481](#):
>
> seem to have to refocus now staff layoff after unrealistic expectations

this link doesn’t seem to work. at least for me. or maybe it wasn’t meant to be one…but it looked like

---

<div class="post-metadata">

**Author:** ![meditans](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/meditans/32/1768_2.png) [@meditans](https://swi-prolog.discourse.group/u/meditans)\
**Post date:** [February 25, 2024, 3:06pm UTC](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160/72 "2024-02-25T15:06:04Z")

</div>

There were some good points in your replies @anon95304481, however, due to numerous deleted posts, it becomes quite a challenge to isolate crucial details.

There are indeed some touchy technical aspects:

- Haskell lacks a termination checker and accepts general recursion. As a result, certain expressions don’t terminate (and so they don’t have a normal form). Regardless, our intuition on the runtime’s behaviour is grounded in the small step reduction semantics of the terminating fragment.

- Haskell types barely qualify as ‘types’ as defined in type theory. This discrepancy is largely because of the semantic complexities brought about by laziness and unboxed types, with the technical aspect being that `undefined` inhabits all types. Despite this, type theory often forms the basis of our discussions about the language’s features.

- Similarly, `Hask`, broadly defined as the category comprising Haskell types and functions, is not a category strictly speaking. And yet, we often draw upon categorial intuitions in the language’s abstractions.

In reference to my previous post that aimed to highlight what for me is a ‘significant’ difference, these technicalities appear tangential, akin to focusing excessively on the finger when one is attempting to point at the moon. But you’re right that I have used ‘haskell’ here as a platonic ideal more than an actual implementation.

[Previous page](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160.md?page=1)

[Next page](https://swi-prolog.discourse.group/t/the-similarity-between-haskell-and-prolog/7160.md?page=3)
