Purescript: Template Data Template Template

While this example is contrived, why can't I use a wildcard if the data constructor is ignored?

module Main where

import Prelude
import Control.Monad.Eff.Console (log)

data Person = Amy { name :: String  } | George { name :: String  }

--Implementations Options Below

main = log $ personToString $ George  { name: "George" }

Error

personToString :: Person -> String
personToString (Amy { name: n }) = n
personToString (George { name: n }) = n

Error

personToString :: Person -> String
personToString (_ { name: n }) = n

http://try.purescript.org/?session=a1503b9a-0546-7832-39b0-6321a89ef2e3

Unable to parse module:
  unexpected {
  expecting ::, operator or )
+4
source share
2 answers

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

+6

, , , :

data AmyOrGeorge = Amy | George

data Person = Person AmyOrGeorge { name :: String  }

personToString (Person _ { name: n }) = n

, , .

0

Source: https://habr.com/ru/post/1685835/


All Articles