October 21, 2008

Очень строгая типизация

Волею судеб я теперь играюсь с F#. (Сначала вроде бы увлёкся Haskell’ом, но потом понял, что F# мне как-то ближе, потому как он весь насквозь .net-ный). Если кто не знает, то язык этот – первый и пока что, кажется, единственный функциональный язык для платформы .net. Любители тонкостей скажут, что не такой уж он и функциональный, скорее мультипарадигменный (ох и сложное слово, надо его спеллчекером…), и будут правы. Так и есть, но я лично рассматриваю его как площадку для игр с функциональным программированием. И вот до чего я доигрался.

Есть у меня один микропроект. Даже не проект, а так, игрушка, которую я решил реализовать на F#, чтобы и утилитку полезную получить и с новым языком разобраться. Писал я писал, разбирался-разбирался и в один прекрасный момент понадобилось мне создать web запрос, да не простой, а с кукисами. Как бы я поступил в C#:

HttpWebRequest req =
(HttpWebRequest)WebRequest.Create("http://google.com");
req.CookieContainer.Add(new Cookie("my_cookie", "hello"));

Самая главная часть этого небольшого куска кода во второй строке, где создаётся WebRequest. Видите, как занимательно его приходится создавать? При помощи WebRequest.Create, который уже сам определяет какой конкретный тип запроса надо создать. В данном случае он создаст HttpWebRequest, поэтому преобразование типа здесь отлично сработает и даст нам доступ ко всем методам и свойствам, которые присущи http запросу.

В чём сложность с точки зрения F#? Как оказалось, в его строгой типизации.

let req = WebRequest.Create("http://google.com")
(* will cause an error *)
let httpreq = req :> HttpWebRequest

Архитектура библиотеки классов, как оказалось, не предполагает возможности создания экземпляров HttpWebRequest самих по себе, всё происходит исключительно через WebRequest.Create, а приведение типа объекта от более общего к более частному, получается, невозможно, а CookieContainer есть только в конкретном типе. Я пытался использовать обходные пути, типа Convert.ChangeType, но он, оказывается, возвращает вообще Object, и в итоге необходимо ещё более невозможное приведение типа :-)

Вот такая вот слишком строгая типизация. Если у кого есть мысли как это обойти – welcome!


This page is powered by Blogger. Isn't yours?