简体   繁体   中英

record syntax on a GADT-style data type declaration issue

I'm trying to make the following compile ( record syntax on a GADT-style ) :

{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
module Gsd.CLI.Steps where

import System.Console.Byline
import Data.Text

import Gsd.Clients
import Gsd.Read.Workspace
import Gsd.Read.Goal

type ErrorDescription = String
type WorkOnWorkspacesStepHandle = Clients -> Byline IO ()
type WorkOnAWorkspaceStepHandle = Clients -> Workspace ->  WorkOnWorkspacesStepHandle -> Byline IO ()
type WorkOnAGoalStepHandle      = Clients -> Workspace -> Goal ->  WorkOnAWorkspaceStepHandle -> WorkOnWorkspacesStepHandle -> Byline IO ()



data StepName = WorkOnWorkspaces | WorkOnAWorkspace | WorkOnAGoal

data Step a  where
  WorkOnWorkspacesStep  { workOnWorkspaces:: WorkOnWorkspacesStepHandle, clients::Clients } :: Step WorkOnWorkspaces
  WorkOnAWorkspaceStep  { workOnWorkspace::  WorkOnAWorkspaceStepHandle, clients::Clients, workspace::Workspace , workOnWorkspaces:: WorkOnWorkspacesStepHandle} ::  Step WorkOnAWorkspace
  WorkOnAGoalStep       { workOnAGoal ::     WorkOnAGoalStepHandle,      clients::Clients, workspace::Workspace,  goal::Goal , workOnWorkspace::  WorkOnAWorkspaceStepHandle, workOnWorkspaces:: WorkOnWorkspacesStepHandle} :: Step WorkOnAGoal

the compiler doesn't like the data Step a syntax I have used

/Users/nhenin/dev/gsdFlow/src/Gsd/CLI/Steps.hs:25:25: error: parse error on input ‘{’
   |
25 |   WorkOnWorkspacesStep  { workOnWorkspaces:: WorkOnWorkspacesStepHandle, clients::Clients } :: Step WorkOnWorkspaces
   |                         ^

                    ^

I'm following this example :

  data Term a where
      Lit    { val  :: Int }      :: Term Int
      Succ   { num  :: Term Int } :: Term Int
      Pred   { num  :: Term Int } :: Term Int
      IsZero { arg  :: Term Int } :: Term Bool  
      Pair   { arg1 :: Term a
             , arg2 :: Term b
             }                    :: Term (a,b)
      If     { cnd  :: Term Bool
             , tru  :: Term a
             , fls  :: Term a
             }                    :: Term a

Which does not compile as well surprisingly...

The correct syntax is (crazy):

data Foo a where
  Bar :: { fd1 :: T1, fd2 :: T2 } -> Foo b
  --- etc.

So in this case you might want:

data Step a  where
  WorkOnWorkspacesStep ::
    { workOnWorkspaces:: WorkOnWorkspacesStepHandle
    , clients::Clients } ->
    Step WorkOnWorkspaces
  WorkOnAWorkspaceStep ::
    { workOnWorkspace::  WorkOnAWorkspaceStepHandle
    , clients::Clients
    , workspace::Workspace
    , workOnWorkspaces:: WorkOnWorkspacesStepHandle } ->
    Step WorkOnAWorkspace
  WorkOnAGoalStep ::
    { workOnAGoal ::     WorkOnAGoalStepHandle
    , clients::Clients
    , workspace::Workspace
    , goal::Goal
    , workOnWorkspace:: WorkOnAWorkspaceStepHandle
    , workOnWorkspaces:: WorkOnWorkspacesStepHandle } ->
    Step WorkOnAGoal

For reference, see the GHC user guide (near the bottom of the linked section).

EDIT: Unfortunately, this appears to not be actually legal

However, for GADTs there is the following additional constraint: every constructor that has a field f must have the same result type (modulo alpha conversion)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM