I'm new to XSD. I have a structure which I need to represent in XSD:
struct
{
int num;
char token[10]
char value[20][10];
} test;
How do I mention "value" in XSD? I can represent other elements as:
<complexType name=test>
<sequence>
<element name='num' type='int'/>
<element name='token' type='string' minOccurs='0' maxOccurs='unbounded'/>
</sequence>
</complexType>
This XSD will be used to generate C++ code
Thanks
The following schema describes your data, producing XML that is fairly concise.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2019 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="test">
<xs:complexType>
<xs:sequence>
<xs:element name="num" type="xs:int" />
<xs:element name="token" type="ListOf10Chars" />
<xs:element name="value" type="ListOf10Chars" minOccurs="20" maxOccurs="20" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CharType">
<xs:restriction base="xs:string">
<xs:length value="1" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ListChars">
<xs:list itemType="CharType" />
</xs:simpleType>
<xs:simpleType name="ListOf10Chars">
<xs:restriction base="ListChars">
<xs:minLength value="10" />
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2019 (https://www.liquid-technologies.com) -->
<test>
<num>3281</num>
<token>A b c d e f g h i j</token>
<value>0 b c d e f g h i j</value>
<value>1 b c d e f g h i j</value>
<value>2 b c d e f g h i j</value>
<value>3 b c d e f g h i j</value>
<value>4 b c d e f g h i j</value>
<value>5 b c d e f g h i j</value>
<value>6 b c d e f g h i j</value>
<value>7 b c d e f g h i j</value>
<value>8 b c d e f g h i j</value>
<value>9 b c d e f g h i j</value>
<value>0 b c d e f g h i j</value>
<value>1 b c d e f g h i j</value>
<value>2 b c d e f g h i j</value>
<value>3 b c d e f g h i j</value>
<value>4 b c d e f g h i j</value>
<value>5 b c d e f g h i j</value>
<value>6 b c d e f g h i j</value>
<value>7 b c d e f g h i j</value>
<value>8 b c d e f g h i j</value>
<value>9 b c d e f g h i j</value>
</test>
Related
I've been trying to make a combinator with this type signature:
(a -> b -> c) -> (c -> d -> e) -> a -> b -> d -> e
I've been through Data.Aviary.Birds and all the tacit programming help sites that I can find, but to no avail. Also, if there's a general algorithm to make these, it would be greatly appreciated but not necessary.
Our definition will start like this:
foo :: (a -> b -> c) -> (c -> d -> e) -> a -> b -> d -> e
foo abc cde a b d = e
Now let's fill in the missing bits.
We need an e; the only way to get that is by applying the second function to a c and d.
e = cde c d
We are already given a d, but we need a c. How do we get a c? By applying the first function to an a and a b.
c = abc a b
We are given both of these, so we're done.
foo :: (a -> b -> c) -> (c -> d -> e) -> a -> b -> d -> e
foo abc cde a b d = e
where
e = cde c d
c = abc a b
We might stop here. This is a perfectly good definition.
But if we want to try to make it more terse, let's start by substituting the definition of e
foo abc cde a b d = cde c d
where
c = abc a b
and then of c
foo abc cde a b d = cde (abc a b) d
We immediately see that we can eta reduce to remove the d.
foo abc cde a b = cde (abc a b)
The type is now slightly more general. d -> e has collapsed into one type variable, since it can actually be anything.
foo :: (a -> b -> c) -> (c -> de) -> a -> b -> de
We can now see in the aviary that our combinator is actually the blackbird, flipped.
blackbird :: (c -> d) -> (a -> b -> c) -> a -> b -> d
foo :: (a -> b -> c) -> (c -> de) -> a -> b -> de
foo = flip blackbird
And indeed if we look at the source for the blackbird, it looks much like what we have written.
-- | B1 combinator - blackbird - specs 'oo'.
blackbird :: (c -> d) -> (a -> b -> c) -> a -> b -> d
blackbird f g x y = f (g x y)
Can we go more point-free? We might consider uncurrying abc
foo abc cde a b = cde (uncurry abc (a, b))
rewriting this nesting with function composition
foo abc cde a b = (cde . uncurry abc) (a, b)
and currying back again
foo abc cde a b = curry (cde . uncurry abc) a b
And now we can chop off two more parameters.
foo abc cde = curry (cde . uncurry abc)
We should definitely stop here. But what if we now flip the arguments
foo = flip $ \cde abc -> curry (cde . uncurry abc)
rewrite the right half to make it point-free
foo = flip $ \cde abc -> (curry . ((cde .) . uncurry)) abc
and eta reduce once more
foo = flip $ \cde -> curry . ((cde .) . uncurry)
and take one final ridiculous step
foo = flip $ (curry .) . (. uncurry) . (.)
We are now point-free!
There's a really easy way: cheat. Let's start by finding out what function we want. For this, we go to Djinn. Type in
f :: (a -> b -> c) -> (c -> d -> e) -> a -> b -> d -> e
and it comes back with
f a b c d = b (a c d)
Nice. Now head over to pointfree.io. Paste in the definition from Djinn, and it says
f = flip ((.) . (.))
Done.
Fd1 = {AB --> C, D --> E, E --> C}
Fd2 = { AB --> C, D --> E, AB --> E, E --> C}
are these two FD's are equivalent or not, i think they are. But in the answer it's shown as not equivalent.
You cannot produce AB → E from dependencies in the first set.
To mathematically prove their (in)equivalence, you should build closures for both sets and compare the closures.
There are a few simple induction rules to build the a closure. Quoting Wikipedia on Functional Dependency, the axioms are:
Reflexivity: If Y is a subset of X, then X → Y
Augmentation: If X → Y, then XZ → YZ
Transitivity: If X → Y and Y → Z, then X → Z
with by a few rules that follow from them:
Union: If X → Y and X → Z, then X → YZ
Decomposition: If X → YZ, then X → Y and X → Z
Pseudotransitivity: If X → Y and WY → Z, then WX → Z
Composition: If X → Y and Z → W, then XZ → YW
Using these rules and axioms, one can build a closure for a FDS.
Omitting trivial dependencies (the ones where right side is included into left side), first set { AB → C (1), D → E (2), E → C (3) } gives:
AB → C (1)
ABD → CE, ABD → C, ABD → E (composition 1+2, decomposition)
ABDE → CE, ABDE → C (composition 1+2+3, decomposition)
ABE → C (composition 1+3)
D → E, D → C, D → CE (2, transitivity 2+3, union)
DE → CE, DE → C (composition 2+3, decomposition)
E → C (3)
And the second set { AB → C (1), D → E (2), E → C (3), AB → E (4) } gives:
AB → C, AB → E, AB → CE (1, 4, union 1+4)
ABD → CE, ABD → C, ABD → E (composition 1+2, decomposition)
ABDE → CE, ABDE → C (composition 1+2+3, decomposition)
ABE → C (composition 1+3)
D → E, D → C, D → CE (2, transitivity 2+3, union)
DE → CE, DE → C (composition 2+3, decomposition)
E → C (3)
The second closure has AB → E, AB → CE, which is not present in the first closure, therefore original sets are different.
I'm playing around with type-aligned sequences, and in particular I'm messing around with the idea of folding them. A foldable type-aligned sequence looks something like this:
class FoldableTA fm where
foldMapTA :: Category h =>
(forall b c . a b c -> h b c) ->
fm a b d -> h b d
foldrTA :: (forall b c d . a c d -> h b c -> h b d) ->
h p q -> fm a q r -> h p r
foldlTA :: ...
It's pretty easy to implement foldrTA in terms of foldMapTA by first using foldMapTA to convert the sequence to a type-aligned list in the naive way (i.e., using the type-aligned list category) and then folding over that list. Unfortunately, this can be quite inefficient because long lists may be prepended to short ones. I've been trying to figure out a way to use a trick similar to the one used in Data.Foldable to define the right and left folds more efficiently, but the types are making me dizzy. Endo does not seem general enough to do the trick, and every step I take in other directions leads me to more type variables than I can keep track of.
I found that this typechecks:
{-# LANGUAGE RankNTypes #-}
module FoldableTA where
import Control.Category
import Prelude hiding (id, (.))
class FoldableTA fm where
foldMapTA :: Category h => (forall b c . a b c -> h b c) -> fm a b d -> h b d
foldrTA :: (forall b c d . a c d -> h b c -> h b d) -> h p q -> fm a q r -> h p r
foldrTA f z t = appEndoTA (foldMapTA (\x -> TAEndo (f x)) t) z
newtype TAEndo h c d = TAEndo { appEndoTA :: forall b. h b c -> h b d }
instance Category (TAEndo h) where
id = TAEndo id
TAEndo f1 . TAEndo f2 = TAEndo (f1 . f2)
No idea if it makes any sense, but with so many type indexes around, I doubt that there is much type-checking code that does not make sense.
Haskell's Data.Bifunctor is basically:
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
I could find a Biapply as well. My question is, why isn't there a complete bi-hierarchy (bierarchy?) like:
class Bifunctor f => Biapplicative f where
bipure :: a -> b -> f a b
biap :: f (a -> b) (c -> d) -> f a c -> f b d
class Biapplicative m => Bimonad m where
bibind :: m a b -> (a -> b -> m c d) -> m c d
bireturn :: a -> b -> m a b
bireturn = bipure
bilift :: Biapplicative f => (a -> b) -> (c -> d) -> f a c -> f b d
bilift f g = biap $ bipure f g
bilift2 :: Biapplicative f => (a -> b -> c) -> (x -> y -> z) -> f a x -> f b y -> f c z
bilift2 f g = biap . biap (bipure f g)
Pair is an instance of these:
instance Bifunctor (,) where
bimap f g (x,y) = (f x, g y)
instance Biapplicative (,) where
bipure x y = (x,y)
biap (f,g) (x,y) = (f x, g y)
instance Bimonad (,) where
bibind (x,y) f = f x y
And types like...
data Maybe2 a b = Fst a | Snd b | None
--or
data Or a b = Both a b | This a | That b | Nope
...would IMO have instances as well.
Are there not enough matching types? Or is something concerning my code deeply flawed?
A monad in category theory is an endofunctor, i.e. a functor where the domain and codomain is the same category. But a Bifunctor is a functor from the product category Hask x Hask to Hask. But we could try to find out what a monad in the Hask x Hask category looks like. It is a category where objects are pairs of types, i.e. (a, b), and arrows are pairs of functions, i.e. an arrow from (a, b) to (c, d) has type (a -> c, b -> d). An endofunctor in this category maps pairs of types to pairs of types, i.e. (a, b) to (l a b, r a b), and pairs of arrows to pairs of arrows, i.e.
(a -> c, b -> d) -> (l a b -> l c d, r a b -> r c d)
If you split this map function in 2, you'll see that an endofunctor in Hask x Hask is the same as two Bifunctors, l and r.
Now for the monad: return and join are arrows, so in this case both are 2 functions. return is an arrow from (a, b) to (l a b, r a b), and join is an arrow from (l (l a b) (r a b), r (l a b) (r a b)) to (l a b, r a b). This is what it looks like:
class (Bifunctor l, Bifunctor r) => Bimonad l r where
bireturn :: (a -> l a b, b -> r a b)
bijoin :: (l (l a b) (r a b) -> l a b, r (l a b) (r a b) -> r a b)
Or separated out:
class (Bifunctor l, Bifunctor r) => Bimonad l r where
bireturnl :: a -> l a b
bireturnr :: b -> r a b
bijoinl :: l (l a b) (r a b) -> l a b
bijoinr :: r (l a b) (r a b) -> r a b
And similar to m >>= f = join (fmap f m) we can define:
bibindl :: l a b -> (a -> l c d) -> (b -> r c d) -> l c d
bibindl lab l r = bijoinl (bimap l r lab)
bibindr :: r a b -> (a -> l c d) -> (b -> r c d) -> r c d
bibindr rab l r = bijoinr (bimap l r rab)
Relative monads
Recently, relative monads have been developed. A relative monad doesn't need to be an endofunctor! If we translate from the paper to Bifunctors in Haskell, you get:
class RelativeBimonad j m where
bireturn :: j a b -> m a b
bibind :: m a b -> (j a b -> m c d) -> m c d
Which defines a monad relative to the bifunctor j. If you pick j to be (,) you get your definition.
The laws are the same as the monad laws:
bireturn jab `bibind` k = k jab
m `bibind` bireturn = m
m `bibind` (\jab -> k jab `bibind` h) = (m `bibind` k) `bibind` h
The first law prevents Maybe2 from being an instance, because bibind has to be able to extract both values from the result of bireturn.
I'm trying to find a more elegant way to write the following code.
class C c where
type E c :: * -> *
class C c => A c where
g :: E c a -> E c a
class (C c, A c) => D c where
f :: E c a -> E c a
instance A c => D c where
f = g
This produces an error.
Test.hs:58:9:
Could not deduce (E c0 ~ E c)
from the context (A c)
bound by the instance declaration at Test.hs:57:10-19
NB: `E' is a type function, and may not be injective
Expected type: E c a
Actual type: E c0 a
Expected type: E c a -> E c a
Actual type: E c0 a -> E c0 a
In the expression: g
In an equation for `f': f = g
Failed, modules loaded: none.
My current solution is to add a dummy variable, from which it can derive
which particular C is in use.
class C c where
type E c :: * -> *
class C c => A c where
g_inner :: c -> E c a -> E c a
g = g_inner undefined
class (C c, A c) => D c where
f_inner :: c -> E c a -> E c a
f = f_inner undefined
instance A c => D c where
f_inner = g_inner
I know this is another instance of associated types not being injective,
but I can't quite figure it out. Sure, E might not be injective, but it
seems somewhere the information that g will work on the particular
(E c) referenced in class D has been lost.
Any explanation, and more importantly better workarounds would be
much appreciated. Thanks!
edit
Okay, I see switching type to data makes the code work.
I'm trying to sound out how this might work. Each c creates a new data type E c. In the instance context, we have to match forall a. ((E) c) a -> ((E) c) a with forall a. ((E) c) a -> ((E) c) a. Denoting F = E c, we are then matching forall a. F a -> F a with itself.
I'm having trouble seeing where things break with the type synonyms (associated types) case. Sure, one could define two instances of A which both have signature (E c) a -> (E c) a. But, why would it be wrong to use the definition from the instance A c which is in scope?
Thanks!!
The problem is that, from just E c a -> E c a, the compiler doesn't know which instance C to choose.
Associated type families are just type synonyms. So the class
class C c => A c where
g :: E c a -> E c a
from the typechecker's perspective may as well be
class C c => A c where
g :: m a -> m a
As the class variable c isn't mentioned, there's no way to determine which instance dictionary should be used to select the function. Although this is because type families aren't injective, I agree that it isn't obvious from the error message that this is the problem.
Using a data family as Daniel Wagner suggests may be the most elegant solution. I've sometimes been able to invert my type families, so that instead of getting an E c for a particular c, I instead choose c based on E c. In this case, that would give:
class E (e :: * -> *) where
type C e :: *
class E e => A e where
g :: e a -> e a
class (A e) => D e where
f :: e a -> e a
instance A e => D e where
f = g
Depending on what else you're doing, this may work for you.
This problem aside, having a separate instance doesn't make much sense. Since A is available as a super class constraint, you can just set f = g as a default method. Doing so will be much less trouble; you probably don't actually want an instance D e where ....