on
이상적인 데이터-모델-최초 개발 접근법
이상적인 데이터-모델-최초 개발 접근법
반응형
실제 응용을 위한 해스켈 및 유형 이론
모든 실제 애플리케이션은 백엔드에서 데이터베이스 또는 17을 사용합니다. 이러한 애플리케이션을 개발하고 유지하는 것은 문제를 해결하려는 많은 시도에도 불구하고 대부분 악몽 같은 경험으로 남아 있습니다. Enterprise Java Beans, Ruby-on-Rails, Meteor — 많은 시도를 했지만, 어느 누구도 겉으로 보기에 간단하고 매우 바람직한 목표를 달성하지 못했습니다.
블로그 플랫폼 애플리케이션이라는 단순화된 사례를 살펴보겠습니다. 블로거에 대한 정보를 다루는 개인형과 블로그 게시물을 대표하는 포스트형이 있습니다. 개인과 포스트 사이에는 "일대다" 관계가 있어서 우리는 항상 주어진 게시물의 작성자가 누구인지 알 수 있고 주어진 저자의 모든 게시물을 검색할 수 있다.
이상적인 세계에서는 위의 그림이 우리가 수동으로 설계해야 할 모든 것, 즉 두 가지 데이터 유형(물론 표시된 것보다 더 많은 필드 포함)과 이들 사이의 관계를 나타내야 한다. 웹 브라우저나 네이티브 UI에 있는 데이터를 지속적으로 저장하거나 프런트 엔드에서 사용하기 위해 상용구 코드를 너무 많이 작성하거나 걱정할 필요가 없습니다. 대신, Haskell typeclasses와 유사한 메커니즘에 의해 우아하게 생성되어야 한다(Java generics 또는 C++ 템플릿은 Haskell에서 가능하지만 훨씬 덜 강력한 것에 대한 명확한 아이디어를 제공합니다).
현실에서 나는 상용구를 써야 한다. 데이터를 유지하려면 모든 유형에 ID를 추가해야 합니다. 비즈니스 논리 코드에 전혀 쓸모가 없습니다! — 각 새 데이터베이스의 API를 별도로 학습합니다. UI요? 시작하지 마세요. 데이터 유형에서 기능에 이르기까지 아래의 모든 계층을 수동으로 코드화해야 합니다.
하지만 그건 그냥 짜증나는 상용구야! 이러한 유형의 순수한 기능은 이미 비즈니스 작업을 해결하는 데 필요한 애플리케이션 도메인에 필요한 모든 사항을 설명하고 있어야 합니다. 이 그림 깊숙한 곳에는 아름답고 우아한 수학적 추상들이 숨겨져 있습니다. 이 추상화들은 우리가 상용구를 관리하고 양식, 순수 유형, 실체 등 사이에서 필요한 모든 "서비스" 유형과 변환 기능을 생성할 수 있도록 해줍니다. 이러한 추상화를 정의하고 이를 통해 개발자에게 권한을 부여하면 생산성이 향상되고 코드가 더욱 유지 관리 용이해질 수 있습니다.
유형을 사용하여 이 문제를 해결하는 한 가지 접근 방식
(시스템-FC 해스켈이 사용하는 것이 아니라 완전한 직관적 유형 이론의 종속 유형을 필요로 하는) 이상적인 유형 중심 환경에서, 나는 다음과 유사한 내 유형을 정의할 수 있기를 원한다.
data Person = Person { name :: String, dob :: Date, ... } data Post = Post { title :: String, body :: String, createdAt :: Date, ... } type WhoIsAuthor = Post -> Person type FindPosts = Person -> [Post] ``` 그런 다음 몇 가지 강력한 파라메트릭 유형 메커니즘을 사용하여 나머지를 처리합니다. 예를 들어, 사용하는 스토리지 백엔드에 관계없이 모든 CRUD(및 기타) 작업을 추상화하는 엔티티 매개 변수 유형을 원합니다. ```js data Entity a::Type db::DatabaseContext = Entity { data :: a, } ``` 위의 형식은 DatabaseContext 형식의 값에 따라 달라지기 때문에(TypeClass가 있는 전체 형식일 수도 있고, 값이 아닌 Type Theory에서 --type이라고 불리는 형식일 수도 있음) 이 구조는 불행하게도 Haskell에서는 불가능하다. 하지만 얘야, 내가 갖고 싶어! (이드리스에서 가능할까?) 가능하다면 엔터티 포스트 몽고컨텍스트나 엔터티 퍼스널 AmazonRedsshift컨텍스트와 붐을 쓰겠습니다! — 추악하고 반복적인 상용구 한 줄 없이 순수한 데이터 유형을 저장, 삭제, 찾고, 다른 방법으로 조작할 수 있습니다. 여기서 DatabaseContent는 낮은 수준의 데이터베이스 관련 모든 시스템을 숨깁니다. 하지만, 이것은 나의 순수한 타입을 유지하는 것에만 신경을 쓰지만, 그들 사이의 관계는 어떨까요? 나는 그 게시물의 작성자가 누구인지 정말 알고 싶다. 여기서는 다음과 같은 보다 복잡한 다중 매개 변수 유형을 사용합니다. ```js instance Database MongoContext Person Post WhoIsAuthor FindPosts where ...
이러한 유형 클래스는 관계를 정의하는 유형(WhoIsAuthor 및 FindPosts)을 포함하여 내 유형을 살펴보고 필요에 따라 이를 해체하며 내 데이터 모델에 대한 모든 ID와 API를 자동으로 관리하고 지정된 데이터베이스에 저장합니다(이 경우 MongoContext에 의해 정의됨). 이곳이 진정한 마법이 일어나야 하는 곳인데, 하스켈에서도 이드리스에서도 현재 확실히 불가능한 일입니다. 이것은 ID와 테이블 이름뿐만 아니라 이러한 ID와 테이블 이름을 사용하여 다음과 같은 룩업을 구현하는 내 관계 유형의 일부 기능을 포함하여 후드 아래에 엔티티 포스트 MongoContext 등의 인스턴스를 생성합니다.
whoIsAuthor :: WhoIsAuthor -- i.e., Post -> Person getAllPosts :: FindPosts -- i.e., Person -> [Post]
물론, 실제 디자인에서는 엔터티 포스트 몽고컨텍스트와 같은 순수 기능들을 바탕으로 더욱 복잡한 기능들을 만들어내야 할 것입니다. 하지만 그것이 자동으로 이루어지는 한, 우리의 삶을 상당히 단순하게 만들 수 있습니다.
문제는 이러한 유형유형을 정의할 수 없다는 것입니다. 왜냐하면 유형유형은 다른 유형과 잠재적 가치에 의존할 뿐만 아니라 다중 파라미터에 의존할 뿐만 아니라 실제 데이터베이스를 모델링하는 데 유용하기 위해서는 다양한 유형유형 매개변수가 필요합니다. 다음과 같은 선에 따라 정의해야 합니다.
class Database db::DatabaseContext [Type] [Type -> Type] [Type -> [Type]] where ...
즉, 데이터베이스 인터페이스를 관리하는 DatabaseContext의 유형(또는 설계에 따라 값도 달라짐)과 데이터베이스 테이블에 저장되는 임의의 순수 유형 목록 및 관계를 정의하는 순수 유형 간의 함수 목록을 취하여 적절한 CRUD, 검색 등을 생성하는 a 유형입니다.데이터 모델에 동의합니다.
자, 이것이 바로 제가 쓸 수 있기를 원하는 것입니다. 이는 모든 스토리지 백엔드에 동일한 추상화를 제공하며 UI 요소 생성에도 유사한 접근 방식을 사용할 수 있습니다!
불행하게도, 지구상의 어떤 언어도 그러한 구조를 허용하지 않는다. 제 질문은 -- 하나 드시겠습니까? :-)
이제 일부 데이터베이스용 프로덕션 지원 라이브러리에서 이미 사용되고 있는 템플릿 해스켈을 사용하여 해스켈의 유연성에 상당히 근접할 수 있습니다. 그러나, 이것은 분명히 적절한 종속형 구현만큼 깨끗하고 간결하며 아름답지 않다. Template Haskell의 또 다른 두 가지 단점은 제작 앱과 유사한 어떤 것에든 그것을 사용하려 했던 사람이라면 누구나 잘 알고 있다.
유형 패밀리와 제네릭은 단일 유형 CRUD 작업을 자동화할 수 있지만 모든 관계를 사용하여 데이터베이스를 모델링할 수는 없습니다. 다중 매개 변수 및 가변 매개 변수 유형 패밀리가 필요하기 때문입니다. 또한 데이터베이스 컨텍스트를 읽기 또는 상태 모나드에 숨기는 것 외에는 전달하는 옵션이 많지 않지만 테이블 이름은 명시적으로 전달되어야 합니다.
문제를 더 복잡하게 하자면, Haskell은 웹이든 네이티브이든 UI와의 관계가 좋지 않은 것으로 알려져 있기 때문에 약간의 오버헤드가 있는 좋은 자바스크립트 컴파일러가 나올 때까지(ghc-js는 일부 블랙홀 다음으로 우주에서 가장 무거운 것임), 우리는 좋은 것을 만들 가능성이 거의 없다(만약 그것이 실행된다면)t 쉽게 잡을 수 있는 API) 하스켈에 기반한 엔드 투 엔드 애플리케이션 개발 플랫폼.
그러나, 우리가 결국 이것을 가지고 실제 데이터 기반 프로덕션 앱을 지금보다 훨씬 쉽게 만들고 유지 관리하는 작업을 원한다면, 답은 Idris와 Haskell보다 훨씬 더 강력한 타입 시스템을 모든 GHC 확장이 제공하는 데 있을 것이다. 또한 Haskell은 기본적으로 동일한 유형을 Sum Type, Typeclasses, Type Familes 등으로 구분함으로써 약간 혼란스러워한다. 깔끔한 설계는 유형 기반 기능 프로그래밍을 훨씬 더 주류를 이루는 데 도움이 될 수 있다.
이 개략적인 일련의 생각을 읽어주셔서 감사합니다. 그리고 그것을 더 발전시키기 위한 당신의 피드백이 매우 궁금하고 감사할 것입니다!
from http://devcloset.tistory.com/353 by ccl(A) rewrite - 2021-09-12 02:27:14