Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8746177
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T12:09:15+00:00 2026-06-13T12:09:15+00:00

So I have a situation very similar to this (much simplified) code: import Data.Maybe

  • 0

So I have a situation very similar to this (much simplified) code:

import Data.Maybe
import Data.List

data Container a = Container [a] 

-- Assumption: an Element can only obtained from a Container.  The operation
-- guarentees the Element is in the Container.
data Element a = Element (Container a) a

-- This operation is only valid for Elements that have the same Container.
before :: Eq a => Element a -> Element a -> Bool
before (Element (Container xs) x) (Element (Container ys) y) 
    | xs == ys = fromJust (elemIndex x xs) < fromJust (elemIndex y xs)
    | otherwise = error "Elements from different Containers"

How can I use Haskell’s type system (or GHC extensions) to restrict before and similar operations from taking Elements from different Containers? I’ve been looking into GADTs and DataKinds but, well, that’s going to take a long while and I could use some suggestions or pointers. (Another idea I’ve thought of but haven’t worked out: use a similar trick as the ST monad’s s parameter…)

Am I too pessimistic if I conclude that this would require a dependently typed language? Because, as my limited understanding of dependent typing goes, I think that I’m trying to index the Element type by values of the Container type.


EDIT: Just for extra color, this all ultimately arises because I’m trying to define something very much like this:

import Data.Function
import Data.Ix

-- I want to use Elements as Array indexes; so Elements need to know
-- their Container to calculate their Int
instance Eq a => Ix (Element a) where
    -- Ignore how crap this code is
    range (l, u) = map (getSibling l) [getIndex l .. getIndex u]
    index (l,u) i = index (getIndex l, getIndex u) (getIndex i)
    inRange (l,u) i = inRange (getIndex l, getIndex u) (getIndex i)

getIndex :: Eq a => Element a -> Int
getIndex (Element (Container xs) x) = fromJust $ elemIndex x xs

getList :: Element a -> [a]
getList (Element (Container xs) _) = xs

getSibling :: Element a -> Int -> Element a
getSibling (Element (Container xs) _) i = Element (Container xs) (xs!!i)

instance Eq a => Eq (Element a) where
    (==) = (==) `on` getIndex

instance Eq a => Ord (Element a) where
    compare = compare `on` getIndex

All of this code requires that you never “mix” Elements from different Containers.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T12:09:16+00:00Added an answer on June 13, 2026 at 12:09 pm

    You can tell containers apart statically by associating a type with each container. Container elements are tagged with the type to determine whether two given elements came from the same container. This uses -XExistentialQuantification and -XRank2Types. Basically, this is dependent typing, except that types depend on the tag instead of the container value.

    -- Containers with existentially typed tags 'c'
    data Container a = forall c. Container !(OpenContainer c a)
    
    -- Containers with a tag parameter 'c'
    data OpenContainer c a = OpenContainer [a]
    
    -- A container element with a tag parameter 'c'
    data Element c a = Element (OpenContainer c a) a
    
    -- Create a container.  An arbitrary tag is chosen for the container.
    container :: [a] -> Container a
    container = Container . OpenContainer
    
    -- Use a container.  The tag is read.
    openContainer :: Container a -> (forall c. OpenContainer c a -> b) -> b
    openContainer c k = case c of Container c' -> k c'
    
    -- Get a container's elements.  The elements are tagged.
    getElements :: OpenContainer c a -> [Element c a]
    getElements c@(OpenContainer xs) = map (Element c) xs
    

    Any time openContainer is called, it will yield a collection of values belonging to the same container. Two different calls to openContainer will be assumed to refer to different containers.

    -- Ok
    f c = openContainer c $ \oc -> getElements oc !! 0 `before` getElements oc !! 1
    
    -- Error
    f c d = openContainer c $ \oc -> openContainer d $ \od -> getElements oc !! 0 `before` getElements od !! 0
    

    This is safe, but conservative, because it is not based on which container is used, but rather which call to openContainer was used.. Calling openContainer on a container, then calling it again, will produce incompatible elements.

    -- Error
    f c = openContainer c $ \oc -> openContainer c $ \od -> getElements oc !! 0 `before` getElements od !! 1
    

    Now you can write before without explicitly testing for equality. Since both elements have the same index, they must have come from the same container.

    before :: Eq a => Element c a -> Element c a -> Bool
    before (Element (OpenContainer xs) x) (Element _ y) = fromJust (elemIndex x xs) < fromJust (elemIndex y xs)
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a very similar situation to what's described in this question : Engineer
I have a situation very similar to the one in this question: Selective Cache
My situation is very similar to this question . I have an app that
I have a very similar situation to the person who asked: Can I serve
I have a situation where I have 4-5 very similar classes which I'd like
Environment: Apache/2.2.11 (Win32) mod_apreq2-20051231/2.6.2-dev mod_perl/2.0.4-dev Perl/v5.10.0 Situation very similar to what's described in this
I am in a situation very similar to what Steve McConnell's in Code Complete
I have an situation here that looks very like a SELECT N+1 from the
I have a situation where I am loading a very unnormalized record set from
The situation is very simple, I have two panel. In the event of OnMouseOver

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.