Home > Enterprise >  Haskell: Type Error Trying when using generics
Haskell: Type Error Trying when using generics

Time:05-17

I am a Haskell beginner, and when I compile the Haskell source code, when trying to make a function to implement an lazy at least as long as

module Main where

import Data.Maybe

main = undefined

foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
  where
    go :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
    go acc [] = Just acc
    go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
      where
        new_acc :: Maybe b
        new_acc = f x acc

with this error pesky stupid nonsense error, considering (at least for what I know) that this should perfectly work. Because the function go and the function parameter are well designed in the type annotations

dist-newstyle/gh.hs:15:19: error:
    • Couldn't match type ‘b2’ with ‘b’
      ‘b2’ is a rigid type variable bound by
        the type signature for:
          new_acc :: forall b2. Maybe b2
        at dist-newstyle/gh.hs:14:9-26
      ‘b’ is a rigid type variable bound by
        the type signature for:
          foldWhilel :: forall a b.
                        (a -> b -> Maybe b) -> b -> [a] -> Maybe b
        at dist-newstyle/gh.hs:7:1-56
      Expected type: Maybe b2
        Actual type: Maybe b
    • In the expression: f x acc
      In an equation for ‘new_acc’: new_acc = f x acc
      In an equation for ‘go’:
          go acc (x : xs)
            = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
            where
                new_acc :: Maybe b
                new_acc = f x acc
    • Relevant bindings include
        new_acc :: Maybe b2 (bound at dist-newstyle/gh.hs:15:9)
        f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
        foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
          (bound at dist-newstyle/gh.hs:8:1)
   |
15 |         new_acc = f x acc
   |                   ^^^^^^^

dist-newstyle/gh.hs:15:21: error:
    • Couldn't match expected type ‘a’ with actual type ‘a1’
      ‘a1’ is a rigid type variable bound by
        the type signature for:
          go :: forall b1 a1. b1 -> [a1] -> Maybe b1
        at dist-newstyle/gh.hs:10:5-29
      ‘a’ is a rigid type variable bound by
        the type signature for:
          foldWhilel :: forall a b.
                        (a -> b -> Maybe b) -> b -> [a] -> Maybe b
        at dist-newstyle/gh.hs:7:1-56
    • In the first argument of ‘f’, namely ‘x’
      In the expression: f x acc
      In an equation for ‘new_acc’: new_acc = f x acc
    • Relevant bindings include
        xs :: [a1] (bound at dist-newstyle/gh.hs:12:15)
        x :: a1 (bound at dist-newstyle/gh.hs:12:13)
        go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
        f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
        foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
          (bound at dist-newstyle/gh.hs:8:1)
   |
15 |         new_acc = f x acc
   |                     ^

dist-newstyle/gh.hs:15:23: error:
    • Couldn't match expected type ‘b’ with actual type ‘b1’
      ‘b1’ is a rigid type variable bound by
        the type signature for:
          go :: forall b1 a1. b1 -> [a1] -> Maybe b1
        at dist-newstyle/gh.hs:10:5-29
      ‘b’ is a rigid type variable bound by
        the type signature for:
          foldWhilel :: forall a b.
                        (a -> b -> Maybe b) -> b -> [a] -> Maybe b
        at dist-newstyle/gh.hs:7:1-56
    • In the second argument of ‘f’, namely ‘acc’
      In the expression: f x acc
      In an equation for ‘new_acc’: new_acc = f x acc
    • Relevant bindings include
        acc :: b1 (bound at dist-newstyle/gh.hs:12:8)
        go :: b1 -> [a1] -> Maybe b1 (bound at dist-newstyle/gh.hs:11:5)
        f :: a -> b -> Maybe b (bound at dist-newstyle/gh.hs:8:12)
        foldWhilel :: (a -> b -> Maybe b) -> b -> [a] -> Maybe b
          (bound at dist-newstyle/gh.hs:8:1)
   |
15 |         new_acc = f x acc
   |           

CodePudding user response:

The simplest way to fix the error is to remove type signatures for go and new_acc.

You cannot use type signatures this way because say b used in the signature of foldWhilel and b used in the signature of new_acc are two completely different variables that just happen to have similar names. On top of that, (a -> b -> Maybe b) ingo signature is wrong regardless (go has no such parameter, is is using f from an outer scope).

If you want to use b throughout you function with the same meaning, you need to enable and apply Scoped type variables:

{-# Language ScopedTypeVariables #-}

import Data.Maybe

foldWhilel :: forall a b. (a -> b -> Maybe b) -> b -> [a] -> Maybe b
foldWhilel f acc xs = go acc xs
  where
    go :: b -> [a] -> Maybe b
    go acc [] = Just acc
    go acc (x:xs) = if isNothing new_acc then Just acc else go (fromJust new_acc) xs
      where
        new_acc :: Maybe b
        new_acc = f x acc

Demo

  • Related