[<TypeProvider>]
type Sha1Provider (_config: TypeProviderConfig) as self =
    inherit TypeProviderForNamespaces()

    let ns = "FSharp.Data"
    let asm = Assembly.GetExecutingAssembly()
    let hexType = ProvidedTypeDefinition(asm, ns, "Sha1", Some typeof<obj>, HideObjectMethods = true)
    let parameters = [ProvidedStaticParameter("HexString", typeof<string>)]
    let cache = new MemoryCache("Sha1Provider")

    do hexType.DefineStaticParameters(parameters, fun typeName args ->
        let value = 
            lazy
                let root = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>, HideObjectMethods = true)
                let hexString = args.[0] :?> string
                let arr = HexParser.parseString (Some 20) hexString
                let valueProp = ProvidedProperty("Value", typeof<byte[]>, IsStatic = true, 
                                                 GetterCode = (fun _ -> <@@ arr @@>))
                root.AddMember(valueProp)
                root
        cache.GetOrAdd (typeName, value))

    do self.AddNamespace(ns, [hexType])
       self.Disposing.Add <| fun _ -> cache.Dispose()

// usage
let sha1 = Sha1<"08494b448aa5b1de963731c21344f80301020304">.Value // byte[]