bwkam beshoy kamel or bwkam's website Zola 2025-02-06T00:00:00+00:00 https://bwkam.github.io/atom.xml The Power of Figurative Language 2025-02-06T00:00:00+00:00 2025-02-06T00:00:00+00:00 bwkam https://bwkam.github.io/blog/figlang/ <p>I think they are an efficient and concise way to get your point across. A sentence like "Jack is hungry" is brief which normally implies that the meaning it carries is also shallow and unspecific. But, similes and metaphors create an exception to this norm about brief sentences. When you change it to "Jack is hungry as a wolf", it's still brief, but the simile has added dimensionality and depth to the meaning. That is, the pairing simile has upgraded the definition of "hungry" and equipped it with a few layers of depth without having to use or look for a more complicated word that nails down the specific variant you intended to convey with the original phrase. You could've also used an intensifier like "very" to modify this degree of meaning. But, in my opinion, a simile or metaphor is stronger. They're efficient because to exactly describe how Jack is hungry, you could say "Jack is so hungry that he could eat tons of meat, and he's so furious". This has the problem of being lengthy, and possibly lacks a few more descriptions to conceive the desired imagery in your head. Eating lots of meat, and being furious are qualities that a wolf possess—well, stereotypically—so, the sentence could easily be reworded as "Jack is hungry as a wolf". The new sentence is short yet deep, as opposed to the former which is longer and not as deep. You could think of "wolf" as a container of the many unreachable words in your head, that is, "Jack is hungry as a [wolf]" can be rephrased or expanded into "Jack is hungry [{that he can, he is, etc.}-{all the qualities of a wolf}]", and this could end up being a several more sentences while a simile could've done a better job in just a sentence! A shortcoming of this construct though is that the meaning may vary to everyone; it depends on how a wolf looks like in their heads, that is, if they even know what a wolf is. That is true of most usage of figurative language.</p> <p>I would like to also add that the said shortcoming is most likely same one that Jesus took advantage of when he was teaching the people in parables, to divide his listeners and prevent just anyone from understanding them. The meaning of the parables varied across the people, and his disciplines were the only ones who understood them. Everyone else found them obscure.</p> <p>I think it's reasonable to claim that the understanding of metaphors among people is never uniform, as people have uniquely different lived experienced and/or socioeconomic conditions. But, I believe that whether this is a shortcoming, depends on the context. I may have implicitly bound it to usage within literature in my first paragraph, but they are evidently problematic in areas like politics, colloquial conversations, and academia. For example, in physics, it's common to use analogies to approach complex ideas, like electricity to water. But, only temporarily. It's agreed upon to be a great analogy, but they certainly don't hold true anymore when you stretch them too far, and try to understand all electricity's properties from the lens of the analogy. At this point, your brain tries its best to repack it within the confines of the analogy, but this even confuses you more, and you ultimately regret knowing the analogy in first place, as its perhaps the easiest/fastest thought your brain recalls when it attempts to understand the real concept outside of its analogical form, and then you're forced to confront the unfortunate reality with no analogies to help you. I think they are like training wheels; you don't realize you can't ride a bicycle until you take them off. However, their usage in areas like literature and so, is fine for the majority of people I believe—except for some with cognitive disabilities who may struggle to comprehend them. I can also imagine metaphors being used to gate keep information or to secretively communicate.</p> My Haskell Notes 2024-10-26T00:00:00+00:00 2024-10-26T00:00:00+00:00 bwkam https://bwkam.github.io/blog/haskell-bs/ <h2 id="type-ambiguity-with-multi-type-param-typeclasses">type ambiguity with multi type param typeclasses</h2> <p>when we introduce multiple params to typeclasses, haskell is more likely to raise "ambiguity" errors. consider the following example:</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#b48ead;">class </span><span style="color:#a3be8c;">Foo </span><span style="color:#bf616a;">a b </span><span style="color:#b48ead;">where </span><span> </span><span style="color:#8fa1b3;">get </span><span style="color:#b48ead;">:: </span><span style="color:#bf616a;">a </span><span style="color:#b48ead;">-&gt; </span><span style="color:#bf616a;">b </span><span> </span><span style="color:#b48ead;">instance Foo Int</span><span> [</span><span style="color:#b48ead;">Int</span><span>] </span><span style="color:#b48ead;">where </span><span> get x = </span><span style="color:#d08770;">[] </span><span> </span><span style="color:#b48ead;">instance Foo Int String where </span><span> get x = </span><span style="color:#d08770;">[] </span><span> </span><span style="color:#8fa1b3;">foo </span><span style="color:#b48ead;">::</span><span> (</span><span style="color:#b48ead;">Foo </span><span style="color:#bf616a;">a b</span><span>) </span><span style="color:#b48ead;">=&gt; </span><span style="color:#bf616a;">a </span><span style="color:#b48ead;">-&gt; </span><span style="color:#bf616a;">b </span><span>foo a = get a </span></code></pre> <p>now if want to invoke call</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span>foo </span><span style="color:#d08770;">2 </span></code></pre> <p>we get the following error:</p> <pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>• Could not deduce ‘Foo a0 b’ </span><span> from the context: (Foo a b, Num a) </span><span> bound by the inferred type for ‘it’: </span><span> forall {a} {b}. (Foo a b, Num a) =&gt; b </span><span> at &lt;interactive&gt;:1:1-5 </span><span> The type variable ‘a0’ is ambiguous </span><span> Potentially matching instances: </span><span> instance [safe] Foo Int [Int] -- Defined at app/Main.hs:22:10 </span><span> instance [safe] Foo String Int -- Defined at app/Main.hs:25:10 </span><span>• In the ambiguity check for the inferred type for ‘it’ </span><span> To defer the ambiguity check to use sites, enable AllowAmbiguousTypes </span><span> When checking the inferred type </span><span> it :: forall {a} {b}. (Foo a b, Num a) =&gt; b </span></code></pre> <p>this happens because when you call <code>foo 2</code>, haskell tries to resolve <code>Foo a b</code>, which I believe happens before the function is actually evaluted, so it has solid types to operate on. so it sees <code>a</code> in <code>get :: a -&gt; b</code>, and it knows its <code>Int</code> or something. nah dumbass! <code>a</code> is still not a solid type, haskell just puts a <code>Num</code> constraint on it, and that's what it only knows. So both <code>a</code> and <code>b</code> are ambigious. let's be more explicit here</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span>foo (</span><span style="color:#d08770;">2 </span><span>:: </span><span style="color:#d08770;">Int</span><span>) </span></code></pre> <p>Then haskell looks for a <code>Foo Int b</code> instance, do we have one? No. So haskell is confused about which instance of <code>Foo a b</code> you actually want to use, which the error message helpfully provides for you. To fix such an error, you have to be more explicit about the type. i.e</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span>(foo (</span><span style="color:#d08770;">2 </span><span>:: </span><span style="color:#d08770;">Int</span><span>) :: [</span><span style="color:#d08770;">Int</span><span>]) </span></code></pre> <p>tada, now haskell knows that you meant the <code>Foo Int [Int]</code> instance</p> <h2 id="functional-deps">functional deps</h2> <p>with the multi type param extensions, you sometimes want one type to decide the other. e.g</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#b48ead;">class </span><span style="color:#a3be8c;">Foo </span><span style="color:#bf616a;">a b </span><span style="color:#b48ead;">where </span><span> </span><span style="color:#8fa1b3;">get </span><span style="color:#b48ead;">:: </span><span style="color:#bf616a;">a </span><span style="color:#b48ead;">-&gt; </span><span style="color:#bf616a;">b </span></code></pre> <p>this means we can do stuff like</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#b48ead;">instance Foo Int M </span><span> ... </span><span> </span><span style="color:#b48ead;">instance Foo String M </span><span> ... </span></code></pre> <p>this is fine, but sometimes it isn't desirable. we don't want multiple <code>b</code>s for one <code>a</code>. we only want 1:1 so how do we communicate this to haskell? functional deps. (enable the ext)</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#b48ead;">class </span><span style="color:#a3be8c;">Foo </span><span style="color:#bf616a;">a b</span><span> | </span><span style="color:#bf616a;">a</span><span> -&gt; </span><span style="color:#bf616a;">b </span><span style="color:#b48ead;">where </span><span> </span><span style="color:#8fa1b3;">get </span><span style="color:#b48ead;">:: </span><span style="color:#bf616a;">a </span><span style="color:#b48ead;">-&gt; </span><span style="color:#bf616a;">b </span></code></pre> <p>that's it, now if you try the snippet earlier, haskell would complain, you would have to only keep one of them. think if <code>b</code> is some certain certain, it doesn't make sense for a state to be associated with different types.</p> <p>now let's see a more complicated example. the <code>megaparsec</code> library provides a function called <code>single</code>, it's type signature is:</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#8fa1b3;">single </span><span style="color:#b48ead;">:: MonadParsec </span><span style="color:#bf616a;">e s m </span><span style="color:#b48ead;">=&gt; Token </span><span style="color:#bf616a;">s </span><span style="color:#b48ead;">-&gt; </span><span style="color:#bf616a;">m</span><span> (</span><span style="color:#b48ead;">Token </span><span style="color:#bf616a;">s</span><span>) </span></code></pre> <p>roughly, this means that <code>e</code> <code>s</code> and <code>m</code> are related through <code>MonadParsec</code>. that's the signature of the class</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span style="color:#b48ead;">class</span><span> (</span><span style="color:#a3be8c;">Stream </span><span style="color:#bf616a;">s</span><span>, </span><span style="color:#a3be8c;">MonadPlus </span><span style="color:#bf616a;">m</span><span>) =&gt; </span><span style="color:#a3be8c;">MonadParsec </span><span style="color:#bf616a;">e s m</span><span> | </span><span style="color:#bf616a;">m</span><span> -&gt; </span><span style="color:#bf616a;">e s </span><span style="color:#b48ead;">where </span><span> ... </span></code></pre> <p>you see there is a functional dep, which says "m determines e and s". yes so that means we only need to tell it about <code>m</code>, it will take care of <code>e</code> and <code>s</code> if we try evaluate <code>single '\n'</code>, we would get an ambiguity error, because we don't know <code>m</code>, so we don't know <code>s</code> which is the first argument of <code>single</code>. it tries to match <code>Char</code> (what we gave it) against what it knows i.e <code>Token s</code>. Nothing it can do abaout it. let's help it out and give it an explicit type</p> <p>note: it knows <code>Token s ~ Char</code>, but nothing about <code>s</code></p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span>(single &#39;</span><span style="color:#96b5b4;">\n</span><span>&#39;) :: </span><span style="color:#d08770;">Parsec Void String Char </span></code></pre> <p>so because we know <code>Token s ~ Char</code> (hint from '\n'), we observe how haskell matches the types</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span>m </span><span style="color:#d08770;">Char </span><span style="color:#d08770;">Parsec Void String Char </span></code></pre> <p>it sees that the <code>Char</code> is constant in both sides, so it attempts to match <code>m</code> with <code>Parsec Void String</code>, and it should work out. now we know <code>m ~ Parsec Void String</code>, remember when I said that's what we only need? yes, so because of the functional dependency, you can rest assured that there is only one instance of <code>MonadParsec</code> where <code>m ~ Parsec Void String</code>, which means there are only one <code>s</code> and <code>e</code> that can fit in here, and those are the <code>Void</code> and <code>String</code>. So, ultimately haskell knows that we need the <code>MonadParsec Void String (ParsecT Void String Identity)</code>. And if we hoogle it up:</p> <pre data-lang="hs" style="background-color:#2b303b;color:#c0c5ce;" class="language-hs "><code class="language-hs" data-lang="hs"><span> (</span><span style="color:#d08770;">Ord</span><span> e, </span><span style="color:#d08770;">Stream</span><span> s) =&gt; </span><span style="color:#d08770;">MonadParsec</span><span> e s (</span><span style="color:#d08770;">ParsecT</span><span> e s m) </span></code></pre> <p>we can see that there is indeed an instance with the types we employed.</p>