我正在尝试学习一些模板Haskell.作为练习,我写的,可以生成诸如函数isLeft和isRight(灵感来自这个问题).这是我谦虚的尝试:
isA connam = do
ConE nam <- connam
nn <- newName "p"
lamE [varP nn] $ caseE (varE nn) [
match (conP nam [wildP]) ( normalB [| True |] ) [],
match wildP ( normalB [| False |] ) []
]
Run Code Online (Sandbox Code Playgroud)
问题是它只适用于单参数构造函数.罪魁祸首是conP nam [wildP]模式.理想情况下,它看起来应该是conP nam (replicate (numArgs nam) wildP),numArgs函数返回构造函数的参数数量.但是我该如何编写这样的功能呢?我想我需要访问相关的数据声明,但我不知道如何.
这里有另外一个关于这个功能的问题.
我刚开始学习模板Haskell,并坚持使用拼接的简单问题.
在一个模块中,我实现了tupleN回复元组的第N个元素的函数:
tupleN :: Lift a => a -> Int -> Q Exp
tupleN a n = do
(TupE as) <- lift a
return $ as !! n
Run Code Online (Sandbox Code Playgroud)
在Main模块中,我有:
main :: IO ()
main = do
let tup = (1::Int,'a',"hello")
putStrLn $ show $(tupleN $tup 1)
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但事实并非如此.编译器打印错误:
GHC stage restriction: `tup'
is used in a top-level splice or annotation,
and must be imported, not defined locally
In the expression: tup
In the first argument of `tupleN', namely `$tup' …Run Code Online (Sandbox Code Playgroud) 模板Haskell 的文档说QuasiQuoter定义为
data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp,
quotePat :: String -> Q Pat,
quoteType :: String -> Q Type,
quoteDec :: String -> Q [Dec] }
Run Code Online (Sandbox Code Playgroud)
我遇到过silly如下所示的例子.他们如何工作因为他们似乎并没有填写quotePat,quoteType和quoteDec领域?
silly :: QuasiQuoter
silly = QuasiQuoter { quoteExp = \_ -> [| "yeah!!!" |] }
Run Code Online (Sandbox Code Playgroud) 我正在创建一个Yesod子网站,并在一些模板Haskell生成的代码中出现类型错误:
Yesod\DataSource\Data.hs:19:1:
Couldn't match type `[Char]' with `Text'
Expected type: () -> ([Text], [(Text, Text)]) -> Maybe (Route DataSource)
Actual type: () -> ([[Char]], [(Text, Text)]) -> Maybe (Route DataSource)
In the first argument of `\ f_amMs x_amMt -> f_amMs () x_amMt ::
forall a_amMu.
(() -> ([Text], [(Text, Text)]) -> Maybe (Route a_amMu))
-> ([Text], [(Text, Text)]) -> Maybe (Route a_amMu)', namely
`helper_amMr'
In the expression:
\ f_amMs x_amMt -> f_amMs () x_amMt ::
forall a_amMu.
(() -> ([Text], …Run Code Online (Sandbox Code Playgroud) 假设我有这种枚举类型:
data TVShow = BobsBurgers | MrRobot | BatmanTAS
Run Code Online (Sandbox Code Playgroud)
我想定义为实例Read,并Show与以下行为:
show BobsBurgers = "Bob's Burgers"
show MrRobot = "Mr. Robot"
show BatmanTAS = "Batman: The Animated Series"
read "Bob's Burgers" = BobsBurgers
read "Mr. Robot" = MrRobot
read "Batman: The Animated Series" = BatmanTAS
Run Code Online (Sandbox Code Playgroud)
有很多在这些定义重复的,所以我想每种类型的构造函数的字符串相关联,然后生成Show并Read自动从这些关联.这样的事情可能吗?
我使用单一包生成的非常简单的类型级自然.我现在正在尝试向他们添加Ord实例.
{-# LANGUAGE MultiParamTypeClasses, TemplateHaskell, KindSignatures, DataKinds, ScopedTypeVariables, GADTs, TypeFamilies, FlexibleInstances, TypeOperators, UndecidableInstances, InstanceSigs #-}
module Functions where
import Data.Singletons
import Data.Singletons.TH
import Data.Singletons.Prelude
import Data.Promotion.Prelude
singletons [d|
data Nat = Z | S Nat
deriving Eq
instance Ord Nat where
(<=) Z _ = True
(<=) (S _) Z = False
(<=) (S n) (S m) = n <= m
|]
Run Code Online (Sandbox Code Playgroud)
我一直在遇到一个错误.最新的一个是:
src/Functions.hs:10:1:
Couldn't match kind ‘Nat’ with ‘*’
When matching types
n0 :: Nat
t1 :: *
Expected …Run Code Online (Sandbox Code Playgroud) 我有一个类型
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiWayIf #-}
import GHC.Generics
import Data.Aeson.TH
import Data.Aeson.Types
data MyJSONObject = MyJSONObject
{ name :: String
, ptype :: Maybe String
, pid :: Maybe String
, subject :: Maybe String
, message :: Maybe String
} deriving (Show, Generic)
Run Code Online (Sandbox Code Playgroud)
还有更多的Maybe String领域.我FromJSON和ToJSON这个TemplateHaskell功能提供
$(deriveJSON defaultOptions
{
omitNothingFields = True
, fieldLabelModifier = \f -> if
| f == "ptype" -> "type" -- …Run Code Online (Sandbox Code Playgroud) 我想用代码生成替换这个样板:
import qualified Y15.D01
import qualified Y15.D02
import qualified Y15.D03
import qualified Y15.D04
import qualified Y15.D05
import qualified Y15.D06HM
import qualified Y15.D06IO
import qualified Y15.D06ST
import qualified Y15.D07
import qualified Y15.D08
import qualified Y15.D09
import qualified Y15.D10
import qualified Y15.D11
import qualified Y15.D12
import qualified Y15.D13
...
days :: [(String, [String -> IO String])]
days =
[ ("Y15.D01", i2ios [Y15.D01.solve1, Y15.D01.solve2])
, ("Y15.D02", i2ios [Y15.D02.solve1, Y15.D02.solve2])
, ("Y15.D03", i2ios [Y15.D03.solve1, Y15.D03.solve2])
, ("Y15.D04", i2ios [Y15.D04.solve1, Y15.D04.solve2])
, ("Y15.D05", i2ios [Y15.D05.solve1, …Run Code Online (Sandbox Code Playgroud) 我有这个文件:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ExistentialQuantification #-}
module Toy where
import Control.Lens
data Bar = Bar { _barish :: String }
data Foo = forall a. Show a => Foo { _fooish :: a }
$(makeLenses ''Bar)
$(makeLenses ''Foo)
x = barish
y = fooish
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
Toy.hs:15:5:
Not in scope: `fooish'
Perhaps you meant `_fooish' (line 9)
Run Code Online (Sandbox Code Playgroud)
这是我第一次尝试使用存在量词; 我不知道为什么这些功能组合会中断.更令人担忧的是,为什么我没有收到有关makeLenses失败的错误消息?我跑了runhaskell Toy.hs
是否可以在Haskell中创建一个函数,该函数返回数据类型的构造函数列表?
它应该像这样工作:
ghci> getConstructors Bool
[True, False]
ghci> getConstructors Maybe
[Nothing, Just]
Run Code Online (Sandbox Code Playgroud) haskell functional-programming dynamic-programming template-haskell