Search code examples
haskellyesodpersistent

How would I make a generic sort option SelectOpt for all columns?


Is there a more elegant way of writing this: (the code below compiles)

getModelSorterOpt sortOrder sortField = do
    case sortOrder of
        "Asc" ->
            case sortField of
                "id" -> Just   $ Asc ModelId
                "name" -> Just $ Asc ModelName
                "created" -> Just $ Asc ModelCreated
                _ -> Nothing
        "Desc" ->
            case sortField of                                                                                                    
                "id" -> Just   $ Desc ModelId
                "name" -> Just $ Desc ModelName
                "created" -> Just $ Desc ModelCreated
                _ -> Nothing

The main problem is that I can't use a variable instead of the "Asc/Desc" case. Something like the code below, fails to typecheck.

getModelSorterOpt sortOrder sortField = 
                case sortField of                                                                                                    
                    "id" -> Just   $ sortOrder' ModelId
                    "name" -> Just $ sortOrder' ModelName
                    "created" -> Just $ sortOrder' ModelCreated
                    _ -> Nothing
                where sortOrder' = case sortOrder of 
                    "Asc" -> Asc
                    "Desc" -> Desc

GHC says that it doesn't expect ModelId and ModelName to be a part of the same case since they're different types. Which I think is valid. However, Asc ModelId is the same type as Asc ModelName. How do I tell GHC that?


Hammar's initial answer works. This version still doesn't work:

getModelSorterOpt sortOrder sortField = do
        (sortOrder'' ::  EntityField Model a -> SelectOpt Model ) <- sortOrder'
        case sortField of                                                                                                        
            "id" -> Just   $    sortOrder'' ModelId
            "name" -> Just $    sortOrder'' ModelName
            "created" -> Just $ sortOrder'' ModelCreated
            _ -> Nothing
        where sortOrder' = case sortOrder of  
                    "Asc" -> Just Asc 
                    "Desc" -> Just Desc 
                    _ -> Nothing

I get the same error that ModelId and ModelName are of different types. Is this because sortOrder'' is being used monadically?


Solution

  • Try giving sortOrder' a type signature.

    where sortOrder' :: EntityField Model typ -> SelectOpt Model
          sortOrder' = case sortOrder of 
                        "Asc" -> Asc
                        "Desc" -> Desc
    

    This compiles using GHC 7.6.2.