2

I understand that asking “why my code does not work” is not the best question. However, I am asking as I wish to learn more about using monads in Haskell in an algorithmic context for graph theory problems, and took the following code as a starting point to understand how the ST monad would be used in such an algorithm.

I made progress on some simpler algorithms (quick sort) and progressed to Dijkstra’s algorithm. I was unable to compile the following implementation (written in 2012) of Dijkstra’s algorithm: http://www.rosettacode.org/wiki/Dijkstra%27s_algorithm#Haskell

The error I get is the following :

• Non type-variable argument
        in the constraint: MArray (STArray s) e0 m
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        f :: forall (m :: * -> *).
             (MArray (STArray s) e0 m, MArray (STArray s) v m) =>
             Set (a0, v) -> (v, a0) -> m (Set (a0, v))
      In the expression:
        let
          edges = adj_list ! u
          f vertex_queue (v, weight) = do ...
        in foldM f vertex_queue' edges >>= aux
      In a case alternative:
          Just ((dist, u), vertex_queue')
            -> let
                 edges = adj_list ! u
                 f vertex_queue (v, weight) = ...
               in foldM f vertex_queue' edges >>= aux
   |
18 |                 f vertex_queue (v, weight) = do

(PS : this is not for a school assignment, this is just self-motivated), I have tried everything I knew in Haskell (including proper indentations) but couldn’t succeed.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Danish A. Alvi
  • 161
  • 1
  • 8
  • Can you share the program you wrote? Right now we can only see the error. – Willem Van Onsem Oct 04 '21 at 06:50
  • As mentioned, I did not write the code myself. I have shared the link to the code in my question. I can also share the code from the link if you say. – Danish A. Alvi Oct 04 '21 at 06:50
  • Perhaps you should add `{-# LANGUAGE FlexibleContexts #-}` as the error suggests, although it is hard to say if this is a problem with not enabling an extension or just that you made a mistake when designing the algorithm. – Willem Van Onsem Oct 04 '21 at 06:51
  • 1
    what if you add `{-# LANGUAGE FlexibleContexts #-}` to the top of the file? – Willem Van Onsem Oct 04 '21 at 06:51
  • Okay, let me try and I will get back to you! – Danish A. Alvi Oct 04 '21 at 06:52
  • 1
    Wow, it worked! I knew about the Language extensions, but I was unable to decipher that the "Use FlexibleContexts” was a directive to add the extension. I will keep this in mind for the future. I am so thankful to you Willem, I had been stuck on this for the weekend. – Danish A. Alvi Oct 04 '21 at 06:53
  • 1
    perhaps "use the `FlexibleContext` extension" would have been a better error message. – Willem Van Onsem Oct 04 '21 at 06:56
  • when faced with strange and vague new terms you could try taking a long route and internet-search-engine them. of course at the beginning every term is vague and new.... – Will Ness Oct 04 '21 at 06:59

1 Answers1

0

As the error says, the algorithm makes use of the FlexibleContexts extension [haskell.org]. Normally only constraints of the form C t, or C (q t1 t2 … tn) can be used, with C a typeclass and q, t and ti type variables. By enabling the FlexibleContexts, the constraints can also make use of type constructors.

The compiler detects that the type constraints use (MArray (STArray s) e0 m, MArray (STArray s) v m) as context, so with STArray as a type constructor, which is not allowed. The compiler detects this and raises an error that mentions:

(Use FlexibleContexts to permit this)

The compiler thus gives advise on what might fix the problem, although I agree it is a bit "cryptic".

You thus can enable this with a language pragma in the head of the file:

{-# LANGUAGE FlexibleContexts #-}

--- rest of the file ⋮
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555