Emr*_*oin 2 java jvm scala playframework frege
我正在搜索一个新项目的语言.这是基于Web的项目,我想采用REST架构.
我还想要一种函数编程语言.我可以选择Haskell(因为它很酷)和Scala(因为Play Framework).
经过一些研究发现它与语言之间的主要区别后,我找到了Frege,一种在JVM上运行的类似Haskell的语言.
所以我的问题是,因为Frege在JVM上运行,是否可以将Play框架与Frege一起使用?
这是一个简单的应用程序,用于演示如何将Frege与Play结合使用.由于Play支持Java,实际上很容易使用Frege的Java API,即使我们还没有对Frege的本机Play支持.该应用程序基本上是JSON-in和JSON-out.Frege程序从JSON POST请求中读取参数,并使用迎接用户的JSON响应进行响应.
玩conf/routes:
POST /greet helloplay.FregeApplication.greet()
Run Code Online (Sandbox Code Playgroud)
现在弗雷格的实际"业务逻辑":
module helloplay.FregeApplication where
import Data.JSON
import helloplay.Play
data GreetingRequest = GreetingRequest { name :: String }
data GreetingResponse = GreetingResponse { message :: String }
instance FromJSON GreetingRequest where
fromJSON (Struct fs) = do
name <- field "name" fs
pure $ GreetingRequest name
fromJSON invalid = fail ("Invalid JSON for Greeting Request: " ++ show invalid)
instance ToJSON GreetingResponse where
toJSON (GreetingResponse message) = Struct [ assoc "message" message ]
greet :: GreetingRequest -> GreetingResponse
greet request = GreetingResponse $ "Hello, " ++ request.name
webMain :: Request -> IO ResultStatus
webMain request = do
let jsonRequest = parseJSON request.body.asJson.toString
return $ either badRequest (ok . show . toJSON . greet) jsonRequest
{-
- This makes the Frege module extend Play Controller class so that it can be configured to handle a route.
-}
native module type PlayController where {
public static play.mvc.Result greet() {
return frege.runtime.Delayed.forced(
frege.prelude.PreludeBase.TST.performUnsafe(webMain(request()))
);
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们定义了2个与请求和响应相对应的类型以及具有FromJSON和ToJSON类型类实例的JSON转换.该webMain函数接受播放Request并name从JSON请求中读取并返回包含在播放中的JSON响应Result.Status.该webMain功能是为Play控制器提供实现的功能.播放控制器是一个扩展Play的类play.mvc.Controller.我们可以通过声明一个native module内部的Frege源文件使Frege模块扩展Java类.该webMain函数也是一个IO动作,因此我们必须在某些时候评估某些事情,这是底层控制器中的Java方法通过调用Frege ST.performUnsafe然后从可能的thunk强制结果,否则应用程序会温暖上CPU :)
这里的类型,如Request,ResultStatus,PlayController和喜欢的功能ok,badRequest都来自游戏的框架,所以我们必须添加本地绑定弗雷格提其纯度或可能的空值等,这是一件好事,因为弗雷格是一个纯粹的语言,没有一个的概念null,我们必须明确提到的副作用或Maybe针对不同的Scala编译器在那里你可以调用任何Java方法可能空值.
Play的Frege原生绑定:
module helloplay.Play where
data PlayController = native play.mvc.Controller
data Result = pure native play.mvc.Result
data ResultStatus = pure native play.mvc.Results.Status
pure native badRequest play.mvc.Results.badRequest :: String -> ResultStatus
data Request = pure native play.mvc.Http.Request where
pure native body :: Request -> RequestBody
data RequestBody = pure native play.mvc.Http.RequestBody where
pure native asText :: RequestBody -> String
pure native asJson :: RequestBody -> JsonNode
data JsonNode = pure native com.fasterxml.jackson.databind.JsonNode where
pure native asText :: JsonNode -> String
pure native toString :: JsonNode -> String
pure native ok play.mvc.Results.ok :: String -> ResultStatus
Run Code Online (Sandbox Code Playgroud)
这就对了!我们可以运行它:
activator run
然后
$ curl --header "Content-type: application/json" --request POST --data '{"name": "PlayFrege"}' http://localhost:9000/greet
{"message" : "Hello, PlayFrege"}
Run Code Online (Sandbox Code Playgroud)
Frege有一个SBT插件,可用于在Play项目中编译Frege源.如果有人想尝试一下,我已经在Github中推送了这个示例应用程序.
| 归档时间: |
|
| 查看次数: |
593 次 |
| 最近记录: |