constant in typeclass - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Vincent L

Hi, I'd like to define constant in a typeclass whose type doesn't depend on the parameter. For instance :

class RenduInfo a where
  runScript :: IO ()
  getSubDirectoriesOrderedByPriority :: [Text]

The issue is : how do I call such function ?
I tried with the TypeApplication and ScopedTypeVariable extension but it doesn't work :

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE RankNTypes  #-}
{-# LANGUAGE AllowAmbiguousTypes  #-}


extractAllArchives :: RenduInfo a => IO ()
extractAllArchives =
    do
        students <- getEtudiantList
        case students of Nothing -> return ()
                         Just studentLists -> do
                            forM_ subDirectoriesOrderedByPriority $ \ subdir ->
                                runReaderT (unpackArchivesForAll subdir) studentLists
    where
        subDirectoriesOrderedByPriority :: [Text]
        subDirectoriesOrderedByPriority = getSubDirectoriesOrderedByPriority @a

error message says that error: Variable not in scope: a | subDirectoriesOrderedByPriority = getSubDirectoriesOrderedByPriority a

Torsten Schmits

you need to introduce the type variable with a forall a . in the signature of extractAllArchives

Torsten Schmits

alternatively, you can add a Proxy a parameter to getSubdirectories...., then, with ScopedTypeVariables, you can use (Proxy :: Proxy a)

Vincent L

I still get the issue with extractAllArchives :: forall a. RenduInfo a => IO () :(

Torsten Schmits

your error message suggests that a is a term

Vincent L

with

extractAllArchives :: forall a. RenduInfo a => IO ()
extractAllArchives =
    do
        students <- getEtudiantList
        case students of Nothing -> return ()
                         Just studentLists -> do
                            forM_ subDirectoriesOrderedByPriority $ \ subdir ->
                                runReaderT (unpackArchivesForAll subdir) studentLists
    where
        subDirectoriesOrderedByPriority :: [Text]
        subDirectoriesOrderedByPriority = getSubDirectoriesOrderedByPriority @a

error is `` app\Main.hs:75:79: error: Not in scope: type variable a'
|
75 | subDirectoriesOrderedByPriority = getSubDirectoriesOrderedByPriority @a
|


Torsten Schmits

hmm probably missing some other extension :shrug: what if you remove the local signature?

Vincent L

if I remove the @a I get a longer message stating that ghc doesn't know which instance to pick :

app\Main.hs:75:43: error:
    * Could not deduce (RenduInfo a0)
        arising from a use of `getSubDirectoriesOrderedByPriority'
      from the context: RenduInfo a
        bound by the type signature for:
                   extractAllArchives :: forall a. RenduInfo a => IO ()
        at app\Main.hs:65:1-52
      The type variable `a0' is ambiguous
      These potential instance exist:
        instance RenduInfo RenduTD15 -- Defined in `TD15'
    * In the expression: getSubDirectoriesOrderedByPriority
      In an equation for `subDirectoriesOrderedByPriority':
          subDirectoriesOrderedByPriority
            = getSubDirectoriesOrderedByPriority
      In an equation for `extractAllArchives':
          extractAllArchives
            = do students <- getEtudiantList
                 case students of
                   Nothing -> return ()
                   Just studentLists -> ...
            where
                subDirectoriesOrderedByPriority :: [Text]
                subDirectoriesOrderedByPriority
                  = getSubDirectoriesOrderedByPriority
   |
75 |         subDirectoriesOrderedByPriority = getSubDirectoriesOrderedByPriority
   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Torsten Schmits

you're probably missing ScopedTypeVariables

TheMatten

I tried with the TypeApplication and ScopedTypeVariable extension but it doesn't work

BTW, make sure you wrote ScopedTypeVariables

Vincent L

ho yes right !!! thank you

Vincent L

I though I added it but it looks like I had a copy/paste issue