I donβt know exactly why the compiler cannot assume that both types of sums take { name :: String }
as an argument. I do not think that the compiler can do this right now, and I'm not sure if this is possible.
, , , personToString
, Person
. , , . , , , , .
" ".
class DoesHaveName a where
getName :: a -> String
Person
. purescript-generics-rep. . Generic
Person
.
import Data.Generic.Rep (class Generic)
derive instance genericPerson :: Generic Person _
, Data.Generic.Rep, a Person
, from.
import Data.Generic.Rep (class Generic, from)
personToString :: Person -> String
personToString a = getName (from a)
, DoesHaveName
, { name :: String }
.
import Data.Generic.Rep (class Generic, to, from, Sum(..), Rec(..), NoConstructors, Constructor(..), Field(..))
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
instance doesHaveNameConstructor
:: (IsSymbol t0, IsSymbol t1)
=> DoesHaveName (Constructor t0 (Rec (Field t1 String))) where
getName (Constructor (Rec (Field c))) =
case (reflectSymbol (SProxy :: SProxy t1)) of
"name" -> c
_ -> "NoName"
, . . t0
t1
. , . t0
- Sum ( Amy, George). t1
- ( "" ). reflectSymbol
, , . "", , "NoName".
, , DoesHaveName
Sum. , , .
instance doesHaveNameSum
:: (DoesHaveName a, DoesHaveName b)
=> DoesHaveName (Sum a b) where
getName (Inl a) = getName a
getName (Inr b) = getName b
...
data Person
= Amy { name :: String }
| George { name :: String }
| Jim { name :: String }
-- Logs "amy"
log $ personToString (Amy { name: "amy" }
-- Logs "george"
log $ personToString (George { name: "george" }
-- Logs "jim"
log $ personToString (Jim { name: "jim" }
: http://try.purescript.org/?gist=2fc95ad13963e96dd2a49b41f5703e21