Closed dmitriz closed 7 years ago
for taggedSum
if number of props is 0 then it should return a value and it's intentional. it's reflection of semantics of creating new data type In Haskell/PureScript.
I would be happy if we actually change implementation of tagged to:
const tagged = (name, props) => taggedSum(name, {[name]: props})
or just remove it.
the reason it's not quite possible to have same behaviour in tagged
too, is that in case of taggedSum
we are returning object which is Type Representative and it also holds variant constructors and values. but in case of tagged
we are directly returning constructor which is also Type Representative of objects it's constructing.
Actually, technically we can return a value which is also Type Representative of itself:
const tagged = (typeName, fields) => {
const proto = {}
proto.toString = tagged$toString
let typeRep
if (fields.length) {
typeRep = makeValue(fields, proto, [])
} else {
// this way we avoid named function
typeRep = (0, (...args) => makeValue(fields, proto, args))
}
typeRep.toString = typeRepToString
typeRep.prototype = proto
typeRep.is = isType
typeRep[TYPE] = typeName
proto.constructor = typeRep
return typeRep
}
But I would still vote for removing it or using taggedSum in it's implementation.
@safareli
for taggedSum if number of props is 0 then it should return a value and it's intentional. it's reflection of semantics of creating new data type In Haskell/PureScript.
I see, thank you for the explanation.
My Haskell experience is very basic, but I wonder how they distinguish between f
as function and f()
as function call with no arguments?
Another puzzling question (at least for me) resonating your suggestion to possibly deprecate it, is what does the dagger
here bring over the sanctuary-def
, that seems to address the same problem.
Quite confusingly, none of these two libraries seem to mention the other explicitly.
My Haskell experience is very basic, but I wonder how they distinguish between
f
as function andf()
as function call with no arguments?
In Haskell every function takes exactly one argument. ;)
to give some intuition:
data Maybe a = Just a | Nothing
Nothing :: Maybe a
Just :: a -> Maybe a
Just 'c' :: Maybe Char
data Unit = UnitVal
UnitVal :: Unit
data Boolean = True | False
True :: Boolean
False :: Boolean
daggy
helps you to create tagged constructors / sum types. sanctuary-def
helps you to check types of values in Run-time. they are not related (at least to as much as sanctuary and ramda for example). https://github.com/sanctuary-js/sanctuary-union-type would be related once it's developed.
@davidchambers
In Haskell every function takes exactly one argument. ;)
Ah, that means they don't have this problem. :) But we are stuck with it in JS :(
@safareli
data Maybe a = Just a | Nothing
It might be just me, but I would read it as
either Just
function of one argument of Nothing
function of no arguments. :)
Then if Haskell does not distinguish between the two, perhaps we cannot get any intiution to help us with this problem in JS.
This one is a bit confusing:
Nothing :: Maybe a
It does not seem to tell us whether Nothing
is the same for all a
, does it?
daggy
helps you to create tagged constructors / sum types. sanctuary-def helps you to check types of values in Run-time. they are not related (at least to as much as sanctuary and ramda for example). https://github.com/sanctuary-js/sanctuary-union-type would be related once it's developed.
What about Sanctuary's type constructors like the Pair https://github.com/sanctuary-js/sanctuary-def/blob/v0.10.1/index.js#L639
Wouldn't it be not similar to daggy.tagged('Pair', ['first', 'second'])
?
Sorry if I have missed anything.
But we are stuck with it in JS :(
You can just use taggedSum
and then we would deprecated tagged
or implement it using taggedSum
.... either Just function of one argument of Nothing function of no arguments. :)
There is no function of no arguments in haskell you either have a function or not. but you could have function which takes Unit (which has only one value (Boolean has two values)).
What's the point of having a pure function which has no argument and returns a value (if you want to delay computation of the value it makes sense but that's not the case for us). It's same as that same value. so you could just have that value.
From comments of the Pair
Constructor for tuple types of length 2. Arrays are said to represent tuples.
['foo', 42]
is a member ofPair String Number
.
Types defined in sacntuary-type are used for type checking. like the Pair you have linked takes two types one for each slot. and than it's used to validate if some value has shape of Pair and each slot contains valida value. like you can't do new Pair(1,2)
or set some function on it's prototype. The Pair is Constructor types not for values.
@safareli Thank you for clarification. I see it also makes sense from the curried point of view:
// apply twice
f = x => y => x + y
// apply once
f = x => x + 1
// apply 0 times
f = 1
I can see my confusion, it is really a union (or sum) of two separate object constructors, but the additional typecheck functionalities are what make the two libraries appear similar.
In a way, if I understand it correctly, it is a Sum (pun intended) of the type constructors for the union of the record types with typechecks, mixed with the constructor functions for each partial type.
Where the cata
function and the typechecks have of course more general scopes, not just for the records unions.
For instance, your type is either an Integer
value or an Error
record holding the error details. The cata
and partial typechecks should work no differently in this situation.
I would find it helpful to put this library in a more general context.
Is that the direction behind that union-type
project?
Using the official example https://github.com/fantasyland/daggy#daggytaggedsumtypename-constructors
But if I try the
None
part instead, I get error:Instead it is supposed to be used as property, not function. So the way of use depends on the actual value of the array passed. If the array is empty, use as property. Otherwise - as function.
Is it intended?
On the other hand, if I use the
tagged
constructor directly, it is the function:So now I pass the empty array exactly the same way, but this time I have to use it as function. And if I forget, the property itself is also a function, so I won't even get any error, but the result might be unpredictable.
So again, I am puzzled if that is how it is supposed to work.