<div dir="ltr"><div class="gmail_default"><font face="arial, helvetica, sans-serif">Hi!</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">You can use </font><font face="monospace, monospace">-XPolyKinds</font><font face="arial, helvetica, sans-serif"> two have GHC figure out the kinds for you. Your code compiles with that extra option.</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">Is that what you were looking for?</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">Nick</font></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-02-25 16:12 GMT+03:00 Konstantine Rybnikov <span dir="ltr"><<a href="mailto:k-bx@k-bx.com" target="_blank">k-bx@k-bx.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Hi!<br><br></div>I have a problem that seems very basic and fundamental, but at the same time I keep somehow skipping "the right way" to solve it. So I decided to give a try and describe it here.<br><br></div>The task itself is very common. You have some data, which has some property inside of it. Often, you want to write a function that works only on an object with specific property being equal to something, but you can't move it out to type-parameter, because then you get all sorts of problems like you can't use regular lists/vectors anymore and other similar things.<br><br></div>Let's take a look at real-world example to get a better understanding of a problem:<br><br></div>Given a `Vegetable` type with a type that describes it's "type" (saying which concretely veg is it), you need to write a function `embraceOnion`, which would only work on onions (because it doesn't make sense to embrace any other veg).<br><br><a href="https://gist.github.com/k-bx/32b3f6a770ad81330f51" target="_blank">https://gist.github.com/k-bx/32b3f6a770ad81330f51</a><br><div><br>```<br>{-# LANGUAGE DataKinds #-}<br>{-# LANGUAGE KindSignatures #-}<br><br>module Main where<br><br>main :: IO ()<br>main = putStrLn "Hi!"<br><br>data Vegetable = Vegetable { vegName :: String<br> , vetType :: VegType }<br> deriving (Show, Eq)<br>data VegType = Potato<br> | Tomato<br> | Cucumber<br> | Onion<br> deriving (Show, Eq)<br>newtype TypedVegetable (t::VegType) = TypedVegetable Vegetable<br><br>unType :: TypedVegetable (t::VegType) -> Vegetable<br>unType (TypedVegetable v) = v<br><br>-- | bad<br>embraceOnion :: Vegetable -> IO ()<br>embraceOnion veg = putStrLn ("Yay for onion! It's name is: " ++ vegName veg)<br><br>-- | good, but little ugly because of boilerplate<br>embraceOnion2 :: TypedVegetable Onion -> IO ()<br>embraceOnion2 onion = putStrLn ("Yay for onion! It's name is: " ++ vegName (unType onion))<br><br>-- | doesn't work, need to specify kind of `t`<br>newtype TypedLabel1 t a = TypedLabel1 a<br>unTyped1 :: TypedLabel1 t a -> a<br>unTyped1 (TypedLabel1 a) = a<br>embraceOnion3 :: TypedLabel1 Onion Vegetable -> IO ()<br>embraceOnion3 = undefined<br>```<br><br></div><div>Currently, I'm sticking to solution `embraceOnion2` in my code. `embraceOnion3` doesn't work because of:<br><br>```<br>/Users/kb/workspace/typelabels/typelabels.hs<br><br>The first argument of ‘Main.TypedLabel1’ should have kind ‘*’,<br> but ‘Main.Onion’ has kind ‘Main.VegType’<br>In the type signature for ‘Main.embraceOnion3’:<br> Main.embraceOnion3 :: Main.TypedLabel1 Main.Onion Main.Vegetable<br> -> <a href="http://GHC.Types.IO" target="_blank">GHC.Types.IO</a> ()<br>```<br><br></div><div>What are the other options and "state of the art"?<br><br></div><div>Thank you!<br></div></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>