user5610: One fundamental of Haskell is that a string is really a list of characters. Another fundamental is referential transparency, in that a pure function must always give the exact same result when given the same input.
However, these do not seem to be true in actual practice. For example, I created this function:
stringCharList :: String -> [Char] -> Bool
stringCharList a b
    | a==b = True
    | otherwise = False

if I enter (in the repl)
>stringCharList "hello" ['h','e','l','l','o']

I get back True, as expected. However, if I build this function, I get an error (shown below)
vowelz :: Char -> Bool
vowelz a 
    | a `elem` vowels = True
    | otherwise = False
      where vowels = "aeiou"

JWB2.hs:38:22: error:
    • Ambiguous type variable ‘t0’ arising from the literal ‘"aeiou"’
      prevents the constraint ‘(Data.String.IsString
                                  (t0 Char))’ from being solved.
      Relevant bindings include
        vowels :: t0 Char (bound at JWB2.hs:38:13)
      Probable fix: use a type annotation to specify what ‘t0’ should be.
      These potential instances exist:
        instance (a ~ Char) => Data.String.IsString [a]
          -- Defined in ‘Data.String’
        ...plus two instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: "aeiou"
      In an equation for ‘vowels’: vowels = "aeiou"
      In an equation for ‘vowelz’:
          vowelz a
            | a `elem` vowels = True
            | otherwise = False
            where
                vowels = "aeiou"
   |
38 |       where vowels = "aeiou"
   |                      ^^^^^^^


Either of these two alternatives resolves the error
vowelz :: Char -> Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
      where vowels = "aeiou" :: String

-- OR.....

vowelz :: Char -> Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
      where vowels = ['a','e','i','o','u']

I have tracked this down to the declaration of overloaded strings at the top of my experimental/learning hs file:
{-# LANGUAGE OverloadedStrings #-}

if this line is present, I observe the issues described above. If the line is removed, the issues go away and the observed behavior is as expected.
It seems to me that the OverloadedStrings declaration breaks both those fundamentals I listed at the start, which makes it hard to understand how Haskell can be considered "pure". It also suggests that if I want to make modular code that can be incorporated into other projects, I must account for the various hacks and kludges (and perhaps future, not-yet-invented hacks and kludges) or my pure function might break.
Can anyone help me wrap my brain around this?

user5926: Somewhere in the Haskell based libraries String is defined as a type alias as:
type String = [Char]

The problem with your function is that GHC is not able to determine the type of "aeiou". In this case you would need to add a type signature like this (untested but should work):
vowelz :: Char -> Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
   where
     vowels :: String
     vowels = ['a','e','i','o','u']


5610: <p>One fundamental of Haskell is that a string is really a list of characters. Another fundamental is referential transparency, in that a pure function must always give the exact same result when given the same input.</p>
<p>However, these do not seem to be true in actual practice. For example, I created this function:</p>
<pre><code>stringCharList :: String -&gt; [Char] -&gt; Bool
stringCharList a b
    | a==b = True
    | otherwise = False
</code></pre>
<p>if I enter (in the repl)</p>
<pre><code>&gt;stringCharList &quot;hello&quot; ['h','e','l','l','o']
</code></pre>
<p>I get back True, as expected. However, if I build this function, I get an error (shown below)</p>
<pre><code>vowelz :: Char -&gt; Bool
vowelz a 
    | a `elem` vowels = True
    | otherwise = False
      where vowels = &quot;aeiou&quot;
</code></pre>
<pre><code>JWB2.hs:38:22: error:
    • Ambiguous type variable ‘t0’ arising from the literal ‘&quot;aeiou&quot;’
      prevents the constraint ‘(Data.String.IsString
                                  (t0 Char))’ from being solved.
      Relevant bindings include
        vowels :: t0 Char (bound at JWB2.hs:38:13)
      Probable fix: use a type annotation to specify what ‘t0’ should be.
      These potential instances exist:
        instance (a ~ Char) =&gt; Data.String.IsString [a]
          -- Defined in ‘Data.String’
        ...plus two instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: &quot;aeiou&quot;
      In an equation for ‘vowels’: vowels = &quot;aeiou&quot;
      In an equation for ‘vowelz’:
          vowelz a
            | a `elem` vowels = True
            | otherwise = False
            where
                vowels = &quot;aeiou&quot;
   |
38 |       where vowels = &quot;aeiou&quot;
   |                      ^^^^^^^

</code></pre>
<p>Either of these two alternatives resolves the error</p>
<pre><code>vowelz :: Char -&gt; Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
      where vowels = &quot;aeiou&quot; :: String

-- OR.....

vowelz :: Char -&gt; Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
      where vowels = ['a','e','i','o','u']
</code></pre>
<p>I have tracked this down to the declaration of overloaded strings at the top of my experimental/learning hs file:</p>
<pre><code>{-# LANGUAGE OverloadedStrings #-}
</code></pre>
<p>if this line is present, I observe the issues described above. If the line is removed, the issues go away and the observed behavior is as expected.</p>
<p>It seems to me that the OverloadedStrings declaration breaks both those fundamentals I listed at the start, which makes it hard to understand how Haskell can be considered &quot;pure&quot;. It also suggests that if I want to make modular code that can be incorporated into other projects, I must account for the various hacks and kludges (and perhaps future, not-yet-invented hacks and kludges) or my pure function might break.</p>
<p>Can anyone help me wrap my brain around this?</p>
 5926: <p>Somewhere in the Haskell based libraries <code>String</code> is defined as a type alias as:</p>
<pre><code>type String = [Char]
</code></pre>
<p>The problem with your function is that GHC is not able to determine the type of <code>&quot;aeiou&quot;</code>. In this case you would need to add a type signature like this (untested but should work):</p>
<pre><code>vowelz :: Char -&gt; Bool
vowelz a
    | a `elem` vowels = True
    | otherwise = False
   where
     vowels :: String
     vowels = ['a','e','i','o','u']
</code></pre>
