Node.js 电子铝热剂中的效果

Node.js effects in Thermite for Electron

我正在尝试扩展 https://github.com/kRITZCREEK/electron-apps-with-purescript 以添加我要显示其文件名的目录的输入。

但是,我无法获取以下函数进行类型检查(最后两行有问题,最后是第53行):

performAction :: T.PerformAction _ State _ Action
performAction (SetEditText s)           _ _ = void do
  T.cotransform $ _ { dir = s }
performAction (UpdateFiles s)           _ _ = void do
   filenames <- either (const []) id <$> try (readdir s)
   T.cotransform $ _ { names = filenames }

这里的 readdir 来自 Node.FS.Sync 并且有签名

forall eff. String -> Eff (fs :: FS, err :: EXCEPTION | eff) (Array String)

并且 performAction 的类型为

forall t39 t40. Action -> t40 -> {dir :: String, names :: Array String} -> FreeT (CoTransform (Maybe {dir :: String, names :: Array String}) ({dir :: String, names :: Array String} -> {dir :: String, names :: Array String}))

实际错误是

Could not match type at line 53 col 4

FreeT
  (CoTransform t2
     ({ files :: t3
      | t4
      }
      -> { files :: Array String
         | t4
         }
     )
  )
with type
Eff
while trying to match type FreeT
                         (CoTransform t2
                            ({ files :: t3
                             | t4
                             }
                             -> { files :: Array String
                                | t4
                                }
                            )
                         )
                         t5
with type Eff
          ( fs :: FS
          | t0
          )
while checking that expression (apply cotransform) ($1 ->
                                                   { files = f
                                                     }
                                               )
has type Eff
         ( fs :: FS
         | t0
         )
         t1
in value declaration performAction
where t1 is an unknown type
  t0 is an unknown type
  t2 is an unknown type
  t5 is an unknown type
  t4 is an unknown type
  t3 is an unknown type

(整个项目可以在https://github.com/MarkusBarthlen/electron-apps-with-purescript/blob/master/src/Main.purs下找到)

我怀疑我必须使用 lift/liftEff/liftEff'/liftAff 中的任何一个。然而,

performAction :: T.PerformAction _ State _ Action
performAction (UpdateFiles s)           _ _ = void do
   filenames <-  ( lift (either (const []) id <$> try (readdir s)))
   T.cotransform $ _ { names = filenames }

结果

    Could not match type at line 55 col 47
    Eff
     with type
    Aff
    while trying to match type Eff
                         ( fs :: FS
                         | t1
                         )
    with type Aff t0

您可以使用它:

performAction :: forall e. T.PerformAction (fs :: FS | e) State _ Action
performAction (SetEditText s)           _ _ = void do
  T.cotransform $ _ { dir = s }
performAction (UpdateFiles s)           _ _ = void do
   filenames <- lift (liftEff (either (const []) id <$> try (readdir s)))
   T.cotransform $ _ { names = filenames }
  -- T.cotransform $ _ { dir = ""}

liftEff 将您的 Eff 带到 Aff,然后 lift 将其提升到 Thermite 使用的 FreeT ...。额外的 lift 应该不是必需的,但我认为问题在于此处的行和类型类的类型推断,并且在下一个版本中情况应该会好转,我们很可能会有功能依赖性。