bwkambeshoy kamel or bwkam's websiteZola2025-02-06T00:00:00+00:00https://bwkam.github.io/atom.xmlThe Power of Figurative Language2025-02-06T00:00:00+00:002025-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 Notes2024-10-26T00:00:00+00:002024-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;">-> </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;">=> </span><span style="color:#bf616a;">a </span><span style="color:#b48ead;">-> </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) => b
</span><span> at <interactive>: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) => 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 -> 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;">-> </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> -> </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;">-> </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;">=> Token </span><span style="color:#bf616a;">s </span><span style="color:#b48ead;">-> </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>) => </span><span style="color:#a3be8c;">MonadParsec </span><span style="color:#bf616a;">e s m</span><span> | </span><span style="color:#bf616a;">m</span><span> -> </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 '</span><span style="color:#96b5b4;">\n</span><span>') :: </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) => </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>